@promptbook/cli 0.114.0-2 → 0.114.0-3
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/apps/agents-server/next.config.ts +11 -0
- package/apps/agents-server/src/app/layout.tsx +6 -0
- package/esm/index.es.js +677 -199
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +7 -0
- package/esm/scripts/run-codex-prompts/git/coderGitSync.d.ts +43 -0
- package/esm/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -0
- package/esm/scripts/run-codex-prompts/main/resolvePromptRunner.d.ts +8 -1
- package/esm/scripts/run-codex-prompts/ping/buildCoderPingPrompt.d.ts +20 -0
- package/esm/scripts/run-codex-prompts/ping/extractCoderPingAnswer.d.ts +9 -0
- package/esm/scripts/run-codex-prompts/ping/pingCoderHarness.d.ts +23 -0
- package/esm/scripts/run-codex-prompts/ping/printCoderPingResult.d.ts +5 -0
- package/esm/scripts/verify-prompts/verify-prompts.d.ts +5 -0
- package/esm/src/book-components/Chat/utils/$provideServerDomWindow.d.ts +11 -0
- package/esm/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +7 -0
- package/esm/src/cli/cli-commands/coder/ping.d.ts +2 -5
- package/esm/src/cli/cli-commands/coder.d.ts +1 -1
- package/esm/src/cli/cli-commands/common/coderGitSyncCliOptions.d.ts +34 -0
- package/esm/src/cli/cli-commands/common/coderGitSyncCliOptions.test.d.ts +1 -0
- package/esm/src/cli/common/loadPromptsModule.d.ts +16 -0
- package/esm/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -1
- package/esm/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.d.ts +1 -1
- package/esm/src/llm-providers/openai/OpenAiCompatibleRequestManager.d.ts +1 -1
- package/esm/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.d.ts +1 -1
- package/esm/src/llm-providers/openai/utils/loadOpenAiAgentsModule.d.ts +203 -0
- package/esm/src/llm-providers/openai/utils/uploadFilesToOpenAi.d.ts +1 -1
- package/esm/src/utils/misc/createLazyModuleLoader.d.ts +14 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/book-3.0/LiteAgent.ts +11 -9
- package/src/book-components/Chat/utils/$provideServerDomWindow.ts +77 -0
- package/src/book-components/Chat/utils/renderMarkdown.ts +2 -23
- package/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.ts +14 -0
- package/src/cli/cli-commands/agents-server/buildAgentsServer/ensureAgentsServerBuild.ts +1 -0
- package/src/cli/cli-commands/coder/add.ts +40 -12
- package/src/cli/cli-commands/coder/generate-boilerplates.ts +31 -5
- package/src/cli/cli-commands/coder/init.ts +27 -1
- package/src/cli/cli-commands/coder/ping.ts +23 -45
- package/src/cli/cli-commands/coder/verify.ts +27 -12
- package/src/cli/cli-commands/coder.ts +3 -3
- package/src/cli/cli-commands/common/coderGitSyncCliOptions.ts +78 -0
- package/src/cli/cli-commands/run/prepareRunCommandResources.ts +2 -1
- package/src/cli/cli-commands/run/resolveRunInputParameters.ts +2 -1
- package/src/cli/cli-commands/runInteractiveChatbot.ts +2 -1
- package/src/cli/common/$provideLlmToolsForCli.ts +2 -1
- package/src/cli/common/loadPromptsModule.ts +13 -0
- package/src/conversion/archive/loadArchive.ts +2 -1
- package/src/conversion/archive/loadJsZipModule.ts +10 -0
- package/src/conversion/archive/saveArchive.ts +2 -1
- package/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.ts +13 -1
- package/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.ts +13 -1
- package/src/llm-providers/openai/OpenAiAgentKitExecutionTools.ts +6 -2
- package/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.ts +7 -5
- package/src/llm-providers/openai/OpenAiAssistantExecutionTools.ts +1 -1
- package/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.ts +1 -1
- package/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.ts +1 -1
- package/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.ts +1 -1
- package/src/llm-providers/openai/OpenAiCompatibleRequestManager.ts +12 -1
- package/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.ts +1 -1
- package/src/llm-providers/openai/utils/loadOpenAiAgentsModule.ts +11 -0
- package/src/llm-providers/openai/utils/uploadFilesToOpenAi.ts +1 -1
- package/src/other/templates/getTemplatesPipelineCollection.ts +678 -967
- package/src/remote-server/createRemoteClient.ts +12 -1
- package/src/scrapers/website/WebsiteScraper.ts +22 -2
- package/src/utils/misc/createLazyModuleLoader.ts +27 -0
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +750 -266
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +7 -0
- package/umd/scripts/run-codex-prompts/git/coderGitSync.d.ts +43 -0
- package/umd/scripts/run-codex-prompts/git/commitChanges.d.ts +3 -0
- package/umd/scripts/run-codex-prompts/main/resolvePromptRunner.d.ts +8 -1
- package/umd/scripts/run-codex-prompts/ping/buildCoderPingPrompt.d.ts +20 -0
- package/umd/scripts/run-codex-prompts/ping/extractCoderPingAnswer.d.ts +9 -0
- package/umd/scripts/run-codex-prompts/ping/pingCoderHarness.d.ts +23 -0
- package/umd/scripts/run-codex-prompts/ping/printCoderPingResult.d.ts +5 -0
- package/umd/scripts/verify-prompts/verify-prompts.d.ts +5 -0
- package/umd/src/book-components/Chat/utils/$provideServerDomWindow.d.ts +11 -0
- package/umd/src/cli/cli-commands/agents-server/buildAgentsServer/createAgentsServerRuntimeEnvironment.d.ts +7 -0
- package/umd/src/cli/cli-commands/coder/ping.d.ts +2 -5
- package/umd/src/cli/cli-commands/coder.d.ts +1 -1
- package/umd/src/cli/cli-commands/common/coderGitSyncCliOptions.d.ts +34 -0
- package/umd/src/cli/cli-commands/common/coderGitSyncCliOptions.test.d.ts +1 -0
- package/umd/src/cli/common/loadPromptsModule.d.ts +16 -0
- package/umd/src/llm-providers/anthropic-claude/AnthropicClaudeExecutionTools.d.ts +1 -1
- package/umd/src/llm-providers/azure-openai/AzureOpenAiExecutionTools.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionTools.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiAgentKitExecutionToolsToolBuilder.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiAssistantExecutionToolsStreamRunner.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiAssistantExecutionToolsToolRunner.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiCompatibleNonChatPromptCaller.d.ts +1 -1
- package/umd/src/llm-providers/openai/OpenAiCompatibleRequestManager.d.ts +1 -1
- package/umd/src/llm-providers/openai/utils/callOpenAiCompatibleChatModel.d.ts +1 -1
- package/umd/src/llm-providers/openai/utils/loadOpenAiAgentsModule.d.ts +203 -0
- package/umd/src/llm-providers/openai/utils/uploadFilesToOpenAi.d.ts +1 -1
- package/umd/src/utils/misc/createLazyModuleLoader.d.ts +14 -0
- package/umd/src/version.d.ts +1 -1
- package/esm/scripts/run-agent-chat/runCoderPing.d.ts +0 -48
- package/umd/scripts/run-agent-chat/runCoderPing.d.ts +0 -48
package/umd/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('fs/promises'), require('path'), require('crypto'), require('child_process'), require('moment'), require('fs'), require('dotenv'), require('readline'), require('waitasecond'), require('
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'fs/promises', 'path', 'crypto', 'child_process', 'moment', 'fs', 'dotenv', 'readline', 'waitasecond', '
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global._spaceTrim, global.promises, global.path, global.crypto, global.child_process, global.moment, global.fs, global.dotenv, global.readline, global.waitasecond, global.
|
|
5
|
-
})(this, (function (exports, colors, commander, _spaceTrim, promises, path, crypto, child_process, moment, fs, dotenv, readline, waitasecond,
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('colors'), require('commander'), require('spacetrim'), require('fs/promises'), require('path'), require('crypto'), require('child_process'), require('moment'), require('fs'), require('dotenv'), require('readline'), require('waitasecond'), require('crypto-js/enc-hex'), require('crypto-js/sha256'), require('crypto-js'), require('showdown'), require('glob-promise'), require('http'), require('express'), require('socket.io'), require('express-openapi-validator'), require('swagger-ui-express'), require('react'), require('react-dom/server'), require('bottleneck'), require('rxjs'), require('ignore'), require('events'), require('os'), require('mime-types'), require('papaparse'), require('@supabase/supabase-js'), require('url')) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports', 'colors', 'commander', 'spacetrim', 'fs/promises', 'path', 'crypto', 'child_process', 'moment', 'fs', 'dotenv', 'readline', 'waitasecond', 'crypto-js/enc-hex', 'crypto-js/sha256', 'crypto-js', 'showdown', 'glob-promise', 'http', 'express', 'socket.io', 'express-openapi-validator', 'swagger-ui-express', 'react', 'react-dom/server', 'bottleneck', 'rxjs', 'ignore', 'events', 'os', 'mime-types', 'papaparse', '@supabase/supabase-js', 'url'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["promptbook-cli"] = {}, global.colors, global.commander, global._spaceTrim, global.promises, global.path, global.crypto, global.child_process, global.moment, global.fs, global.dotenv, global.readline, global.waitasecond, global.hexEncoder, global.sha256, global.CryptoJS, global.showdown, global.glob, global.http, global.express, global.socket_io, global.OpenApiValidator, global.swaggerUi, global.react, global.server, global.Bottleneck, global.rxjs, global.ignore, global.events, global.os, global.mimeTypes, global.papaparse, null, global.url));
|
|
5
|
+
})(this, (function (exports, colors, commander, _spaceTrim, promises, path, crypto, child_process, moment, fs, dotenv, readline, waitasecond, hexEncoder, sha256, CryptoJS, showdown, glob, http, express, socket_io, OpenApiValidator, swaggerUi, react, server, Bottleneck, rxjs, ignore, events, os, mimeTypes, papaparse, supabaseJs, url) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
8
|
|
|
@@ -31,10 +31,8 @@
|
|
|
31
31
|
var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
32
32
|
var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
|
|
33
33
|
var readline__namespace = /*#__PURE__*/_interopNamespace(readline);
|
|
34
|
-
var prompts__default = /*#__PURE__*/_interopDefaultLegacy(prompts);
|
|
35
34
|
var hexEncoder__default = /*#__PURE__*/_interopDefaultLegacy(hexEncoder);
|
|
36
35
|
var sha256__default = /*#__PURE__*/_interopDefaultLegacy(sha256);
|
|
37
|
-
var JSZip__default = /*#__PURE__*/_interopDefaultLegacy(JSZip);
|
|
38
36
|
var CryptoJS__default = /*#__PURE__*/_interopDefaultLegacy(CryptoJS);
|
|
39
37
|
var showdown__default = /*#__PURE__*/_interopDefaultLegacy(showdown);
|
|
40
38
|
var glob__default = /*#__PURE__*/_interopDefaultLegacy(glob);
|
|
@@ -42,10 +40,7 @@
|
|
|
42
40
|
var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
|
|
43
41
|
var OpenApiValidator__namespace = /*#__PURE__*/_interopNamespace(OpenApiValidator);
|
|
44
42
|
var swaggerUi__default = /*#__PURE__*/_interopDefaultLegacy(swaggerUi);
|
|
45
|
-
var Anthropic__default = /*#__PURE__*/_interopDefaultLegacy(Anthropic);
|
|
46
43
|
var Bottleneck__default = /*#__PURE__*/_interopDefaultLegacy(Bottleneck);
|
|
47
|
-
var OpenAI__default = /*#__PURE__*/_interopDefaultLegacy(OpenAI);
|
|
48
|
-
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
49
44
|
var ignore__default = /*#__PURE__*/_interopDefaultLegacy(ignore);
|
|
50
45
|
var papaparse__default = /*#__PURE__*/_interopDefaultLegacy(papaparse);
|
|
51
46
|
|
|
@@ -63,7 +58,7 @@
|
|
|
63
58
|
* @generated
|
|
64
59
|
* @see https://github.com/webgptorg/promptbook
|
|
65
60
|
*/
|
|
66
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-
|
|
61
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-3';
|
|
67
62
|
/**
|
|
68
63
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
69
64
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -3297,6 +3292,12 @@
|
|
|
3297
3292
|
* @private internal constant of `buildAgentsServer`
|
|
3298
3293
|
*/
|
|
3299
3294
|
const PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION_ENV = 'PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION';
|
|
3295
|
+
/**
|
|
3296
|
+
* Environment variable that disables throwaway webpack filesystem caches for CLI-owned production builds.
|
|
3297
|
+
*
|
|
3298
|
+
* @private internal constant of `buildAgentsServer`
|
|
3299
|
+
*/
|
|
3300
|
+
const PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE_ENV = 'PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE';
|
|
3300
3301
|
/**
|
|
3301
3302
|
* Conservative Next.js build worker count used by CLI-owned Agents Server production builds.
|
|
3302
3303
|
*
|
|
@@ -3321,6 +3322,11 @@
|
|
|
3321
3322
|
[PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION_ENV]: 'true',
|
|
3322
3323
|
}
|
|
3323
3324
|
: {}),
|
|
3325
|
+
...(options.isWebpackFilesystemCacheDisabled
|
|
3326
|
+
? {
|
|
3327
|
+
[PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE_ENV]: 'true',
|
|
3328
|
+
}
|
|
3329
|
+
: {}),
|
|
3324
3330
|
};
|
|
3325
3331
|
}
|
|
3326
3332
|
/**
|
|
@@ -4054,6 +4060,7 @@
|
|
|
4054
4060
|
});
|
|
4055
4061
|
const buildEnvironment = createAgentsServerRuntimeEnvironment(environment, preparedRuntime.nodeModulesPath, {
|
|
4056
4062
|
isNextValidationIgnored: preparedRuntime.isAppPathMaterialized,
|
|
4063
|
+
isWebpackFilesystemCacheDisabled: true,
|
|
4057
4064
|
});
|
|
4058
4065
|
if (!options.isBuildForced &&
|
|
4059
4066
|
(await isAgentsServerBuildCacheCurrent({
|
|
@@ -28230,6 +28237,13 @@
|
|
|
28230
28237
|
* Environment variable read by the shell wrapper to tee live output into the temporary runtime log file.
|
|
28231
28238
|
*/
|
|
28232
28239
|
const PTBK_CODER_LOG_FILE_ENV_NAME = 'PTBK_CODER_LOG_FILE';
|
|
28240
|
+
/**
|
|
28241
|
+
* Log line which separates the raw script input from the raw script output of one execution section.
|
|
28242
|
+
*
|
|
28243
|
+
* Readers of a runtime log split on this marker to look only at what the harness really produced,
|
|
28244
|
+
* without the generated script and the prompt it embeds.
|
|
28245
|
+
*/
|
|
28246
|
+
const SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER = '--- raw output ---';
|
|
28233
28247
|
/**
|
|
28234
28248
|
* Small bash wrapper that preserves stdout/stderr streams while teeing both into the runtime log file.
|
|
28235
28249
|
*/
|
|
@@ -28265,7 +28279,7 @@
|
|
|
28265
28279
|
--- raw input ---
|
|
28266
28280
|
${block(normalizedInput)}
|
|
28267
28281
|
|
|
28268
|
-
|
|
28282
|
+
${SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER}
|
|
28269
28283
|
`);
|
|
28270
28284
|
await promises.appendFile(logPath, `${logSection}\n`, 'utf-8');
|
|
28271
28285
|
}
|
|
@@ -32942,8 +32956,12 @@
|
|
|
32942
32956
|
* `options.includePaths` can restrict staging, `options.onlyPaths` can restrict the commit pathspec,
|
|
32943
32957
|
* `options.excludePaths` can keep temporary artifacts out of the created commit and
|
|
32944
32958
|
* `options.isEmptyCommitAllowed` keeps a round without any file change from failing.
|
|
32959
|
+
*
|
|
32960
|
+
* Note: The temporary commit message file is written inside the project, so it is always excluded from the commit
|
|
32961
|
+
* itself for projects which do not keep the Promptbook temporary directory out of version control.
|
|
32945
32962
|
*/
|
|
32946
32963
|
async function commitChanges(message, options) {
|
|
32964
|
+
var _a;
|
|
32947
32965
|
const projectPath = (options === null || options === void 0 ? void 0 : options.projectPath) || process.cwd();
|
|
32948
32966
|
const commitMessagePath = resolvePromptbookTemporaryPath(projectPath, 'ptbk-coder', 'commit-messages', `COMMIT_MESSAGE_${Date.now()}.txt`);
|
|
32949
32967
|
await promises.mkdir(path.dirname(commitMessagePath), { recursive: true });
|
|
@@ -32951,7 +32969,10 @@
|
|
|
32951
32969
|
try {
|
|
32952
32970
|
const agentEnv = buildAgentGitEnv();
|
|
32953
32971
|
const signingFlag = buildAgentGitSigningFlag();
|
|
32954
|
-
await stageCommitChanges(projectPath, agentEnv, options === null || options === void 0 ? void 0 : options.includePaths,
|
|
32972
|
+
await stageCommitChanges(projectPath, agentEnv, options === null || options === void 0 ? void 0 : options.includePaths, [
|
|
32973
|
+
commitMessagePath,
|
|
32974
|
+
...((_a = options === null || options === void 0 ? void 0 : options.excludePaths) !== null && _a !== void 0 ? _a : []),
|
|
32975
|
+
]);
|
|
32955
32976
|
await runGitCommand({
|
|
32956
32977
|
command: buildGitCommitCommand({
|
|
32957
32978
|
commitMessagePath,
|
|
@@ -42291,6 +42312,91 @@
|
|
|
42291
42312
|
// Note: [🟡] Code for CLI command [agents-server](src/cli/cli-commands/agents-server.ts) should never be published outside of `@promptbook/cli`
|
|
42292
42313
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
42293
42314
|
|
|
42315
|
+
/**
|
|
42316
|
+
* Creates a loader which imports one module on the first call and reuses the very same module afterwards
|
|
42317
|
+
*
|
|
42318
|
+
* Note: [🐌] Heavy third-party dependencies are imported lazily to keep the startup of the Promptbook CLI fast.
|
|
42319
|
+
* A statically imported dependency is loaded every single time the bundle is loaded, even when the running
|
|
42320
|
+
* command never touches it. A lazily imported dependency is loaded only when the feature is really used.
|
|
42321
|
+
*
|
|
42322
|
+
* @example
|
|
42323
|
+
* const loadJsdomModule = createLazyModuleLoader(() => import('jsdom'));
|
|
42324
|
+
* const { JSDOM } = await loadJsdomModule();
|
|
42325
|
+
*
|
|
42326
|
+
* @private internal utility of Promptbook
|
|
42327
|
+
*/
|
|
42328
|
+
function createLazyModuleLoader(importModule) {
|
|
42329
|
+
let importedModulePromise = null;
|
|
42330
|
+
return function loadModule() {
|
|
42331
|
+
if (importedModulePromise === null) {
|
|
42332
|
+
importedModulePromise = importModule();
|
|
42333
|
+
}
|
|
42334
|
+
return importedModulePromise;
|
|
42335
|
+
};
|
|
42336
|
+
}
|
|
42337
|
+
// Note: [🐌] Do not convert the lazy `import(...)` calls back to static `import` statements, it would bring back the
|
|
42338
|
+
// slow startup of the `ptbk` CLI utility
|
|
42339
|
+
|
|
42340
|
+
/**
|
|
42341
|
+
* Loads the interactive terminal prompt library (`prompts`) on demand
|
|
42342
|
+
*
|
|
42343
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast - most commands never ask the user
|
|
42344
|
+
* anything interactively
|
|
42345
|
+
*
|
|
42346
|
+
* @private internal utility of Promptbook CLI
|
|
42347
|
+
*/
|
|
42348
|
+
const loadPromptsModule = createLazyModuleLoader(() => import('prompts'));
|
|
42349
|
+
// Note: [🟡] Code for CLI prompt loading [loadPromptsModule](src/cli/common/loadPromptsModule.ts) should never be published outside of `@promptbook/cli`
|
|
42350
|
+
|
|
42351
|
+
/**
|
|
42352
|
+
* Description block shared by the `ptbk coder` commands which can synchronize their changes with git.
|
|
42353
|
+
*
|
|
42354
|
+
* @private internal utility of `promptbookCli`
|
|
42355
|
+
*/
|
|
42356
|
+
const CODER_GIT_SYNC_DESCRIPTION = _spaceTrim.spaceTrim(`
|
|
42357
|
+
Git synchronization:
|
|
42358
|
+
- --auto-pull pulls the latest changes before this command changes anything
|
|
42359
|
+
- --commit commits the changes made by this command
|
|
42360
|
+
- --auto-push pushes the created commit to the remote repository
|
|
42361
|
+
`);
|
|
42362
|
+
/**
|
|
42363
|
+
* Registers the shared `--commit`, `--auto-push` and `--auto-pull` flags on a `ptbk coder` command.
|
|
42364
|
+
*
|
|
42365
|
+
* Note: Unlike `ptbk coder run`, which commits by default and opts out through `--no-commit`,
|
|
42366
|
+
* these commands never touch git unless the flags are used explicitly.
|
|
42367
|
+
*
|
|
42368
|
+
* @private internal utility of `promptbookCli`
|
|
42369
|
+
*/
|
|
42370
|
+
function addCoderGitSyncOptions(command) {
|
|
42371
|
+
command.option('--commit', 'Commit the changes made by this command with the coding-agent git identity', false);
|
|
42372
|
+
command.option('--auto-push', 'Automatically git push the created commit, requires --commit', false);
|
|
42373
|
+
command.option('--auto-pull', 'Automatically git pull the latest changes before this command changes anything', false);
|
|
42374
|
+
}
|
|
42375
|
+
/**
|
|
42376
|
+
* Converts the Commander git synchronization flags into normalized git synchronization options.
|
|
42377
|
+
*
|
|
42378
|
+
* @private internal utility of `promptbookCli`
|
|
42379
|
+
*/
|
|
42380
|
+
function normalizeCoderGitSyncCliOptions(cliOptions) {
|
|
42381
|
+
if (cliOptions.autoPush && !cliOptions.commit) {
|
|
42382
|
+
throw new NotAllowed(_spaceTrim.spaceTrim(`
|
|
42383
|
+
Flag \`--auto-push\` can be used only together with \`--commit\`.
|
|
42384
|
+
|
|
42385
|
+
**There is nothing to push when the changes are not committed.**
|
|
42386
|
+
|
|
42387
|
+
Actionable hint:
|
|
42388
|
+
- Add \`--commit\`, for example \`ptbk coder init --commit --auto-push\`.
|
|
42389
|
+
`));
|
|
42390
|
+
}
|
|
42391
|
+
return {
|
|
42392
|
+
isCommitEnabled: cliOptions.commit,
|
|
42393
|
+
isAutoPushEnabled: cliOptions.autoPush,
|
|
42394
|
+
isAutoPullEnabled: cliOptions.autoPull,
|
|
42395
|
+
};
|
|
42396
|
+
}
|
|
42397
|
+
// Note: [🟡] Code for CLI git synchronization options [coderGitSyncCliOptions](src/cli/cli-commands/common/coderGitSyncCliOptions.ts) should never be published outside of `@promptbook/cli`
|
|
42398
|
+
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
42399
|
+
|
|
42294
42400
|
/**
|
|
42295
42401
|
* Relative path to the root prompts directory used by Promptbook coder utilities.
|
|
42296
42402
|
*
|
|
@@ -42544,15 +42650,17 @@
|
|
|
42544
42650
|
*/
|
|
42545
42651
|
function $initializeCoderAddCommand(program) {
|
|
42546
42652
|
const command = program.command('add');
|
|
42547
|
-
command.description(_spaceTrim.spaceTrim(`
|
|
42548
|
-
|
|
42653
|
+
command.description(_spaceTrim.spaceTrim((block) => `
|
|
42654
|
+
Add one ready-to-run prompt file to the queue
|
|
42549
42655
|
|
|
42550
|
-
|
|
42551
|
-
|
|
42552
|
-
|
|
42553
|
-
|
|
42554
|
-
|
|
42555
|
-
|
|
42656
|
+
Provide the description as an argument, pipe it through stdin, or run without arguments to type it interactively:
|
|
42657
|
+
- \`ptbk coder add "some new feature"\`
|
|
42658
|
+
- \`ptbk coder add --priority 1 "some new feature"\`
|
|
42659
|
+
- \`ptbk coder add <<EOF ... EOF\`
|
|
42660
|
+
- \`ptbk coder add\`
|
|
42661
|
+
|
|
42662
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
42663
|
+
`));
|
|
42556
42664
|
command.argument('[description]', 'Plain-language description of the feature or task to implement');
|
|
42557
42665
|
command.option('--priority <priority>', 'Priority of the new prompt — higher priorities run first (rendered as trailing `!` markers)', parsePriorityOption, 0);
|
|
42558
42666
|
command.option('--template <template>', _spaceTrim.spaceTrim(`
|
|
@@ -42562,15 +42670,26 @@
|
|
|
42562
42670
|
.map(({ id }) => id)
|
|
42563
42671
|
.join(', ')}) or a markdown file path relative to the current project root.
|
|
42564
42672
|
`));
|
|
42673
|
+
addCoderGitSyncOptions(command);
|
|
42565
42674
|
command.action(handleActionErrors(async (descriptionArgument, cliOptions) => {
|
|
42566
42675
|
const { priority, template: templateOption } = cliOptions;
|
|
42676
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
42677
|
+
const projectPath = process.cwd();
|
|
42567
42678
|
const description = await resolveCoderPromptDescription(descriptionArgument);
|
|
42568
|
-
|
|
42569
|
-
|
|
42679
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
42680
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
42681
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
42682
|
+
const { /* filePath,*/ emojiTag } = await addCoderPrompt({
|
|
42683
|
+
projectPath,
|
|
42570
42684
|
description,
|
|
42571
42685
|
priority,
|
|
42572
42686
|
templateOption,
|
|
42573
42687
|
});
|
|
42688
|
+
await $commitCoderChanges({
|
|
42689
|
+
gitSync,
|
|
42690
|
+
projectPath,
|
|
42691
|
+
commitMessage: `${emojiTag} Add prompt`,
|
|
42692
|
+
});
|
|
42574
42693
|
}));
|
|
42575
42694
|
}
|
|
42576
42695
|
/**
|
|
@@ -42644,7 +42763,8 @@
|
|
|
42644
42763
|
}
|
|
42645
42764
|
return standardInputDescription;
|
|
42646
42765
|
}
|
|
42647
|
-
const
|
|
42766
|
+
const { default: prompts } = await loadPromptsModule();
|
|
42767
|
+
const response = await prompts({
|
|
42648
42768
|
type: 'text',
|
|
42649
42769
|
name: 'description',
|
|
42650
42770
|
message: 'Describe the feature or task to add',
|
|
@@ -43064,9 +43184,11 @@
|
|
|
43064
43184
|
*/
|
|
43065
43185
|
function $initializeCoderGenerateBoilerplatesCommand(program) {
|
|
43066
43186
|
const command = program.command('generate-boilerplates');
|
|
43067
|
-
command.description(_spaceTrim.spaceTrim(`
|
|
43068
|
-
|
|
43069
|
-
|
|
43187
|
+
command.description(_spaceTrim.spaceTrim((block) => `
|
|
43188
|
+
Generate prompt boilerplate files with unique emoji tags
|
|
43189
|
+
|
|
43190
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
43191
|
+
`));
|
|
43070
43192
|
command.option('--count <count>', `Number of prompt boilerplate files to generate`, '5');
|
|
43071
43193
|
command.option('--template <template>', _spaceTrim.spaceTrim(`
|
|
43072
43194
|
Prompt template to use.
|
|
@@ -43075,14 +43197,25 @@
|
|
|
43075
43197
|
.map(({ id }) => id)
|
|
43076
43198
|
.join(', ')}) or a markdown file path relative to the current project root.
|
|
43077
43199
|
`));
|
|
43200
|
+
addCoderGitSyncOptions(command);
|
|
43078
43201
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
43079
43202
|
const { count: countOption, template: templateOption } = cliOptions;
|
|
43080
43203
|
const filesCount = parseFilesCount(countOption);
|
|
43204
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
43205
|
+
const projectPath = process.cwd();
|
|
43206
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
43207
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
43208
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
43081
43209
|
await generatePromptBoilerplate({
|
|
43082
|
-
projectPath
|
|
43210
|
+
projectPath,
|
|
43083
43211
|
filesCount,
|
|
43084
43212
|
templateOption,
|
|
43085
43213
|
});
|
|
43214
|
+
await $commitCoderChanges({
|
|
43215
|
+
gitSync,
|
|
43216
|
+
projectPath,
|
|
43217
|
+
commitMessage: `Prompts ${filesCount}x`,
|
|
43218
|
+
});
|
|
43086
43219
|
return process.exit(0);
|
|
43087
43220
|
}));
|
|
43088
43221
|
}
|
|
@@ -44058,12 +44191,24 @@
|
|
|
44058
44191
|
|
|
44059
44192
|
Checks that the coding harnesses are installed globally and up to date:
|
|
44060
44193
|
${block(listCheckedHarnessLabels())}
|
|
44194
|
+
|
|
44195
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
44061
44196
|
`));
|
|
44062
|
-
command
|
|
44197
|
+
addCoderGitSyncOptions(command);
|
|
44198
|
+
command.action(handleActionErrors(async (cliOptions) => {
|
|
44199
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
44063
44200
|
const projectPath = process.cwd();
|
|
44201
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
44202
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
44203
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
44064
44204
|
const summary = await initializeCoderProjectConfiguration(projectPath);
|
|
44065
44205
|
printInitializationSummary(summary);
|
|
44066
44206
|
await generatePromptBoilerplate({ projectPath, filesCount: 5 });
|
|
44207
|
+
await $commitCoderChanges({
|
|
44208
|
+
gitSync,
|
|
44209
|
+
projectPath,
|
|
44210
|
+
commitMessage: 'Initialize Promptbook Coder',
|
|
44211
|
+
});
|
|
44067
44212
|
await $ensureHarnessInstallations(CODER_INIT_CHECKED_HARNESS_NAMES);
|
|
44068
44213
|
}));
|
|
44069
44214
|
}
|
|
@@ -44085,62 +44230,44 @@
|
|
|
44085
44230
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44086
44231
|
|
|
44087
44232
|
/**
|
|
44088
|
-
* Initializes `coder ping` command for Promptbook CLI utilities
|
|
44089
|
-
*
|
|
44090
|
-
* The command makes one small, isolated harness/model call, prints its result
|
|
44091
|
-
* and reports how long the harness/model turn took.
|
|
44233
|
+
* Initializes `coder ping` command for Promptbook CLI utilities
|
|
44092
44234
|
*
|
|
44093
|
-
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI
|
|
44235
|
+
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI
|
|
44094
44236
|
*
|
|
44095
44237
|
* @private internal function of `promptbookCli`
|
|
44096
44238
|
*/
|
|
44097
44239
|
function $initializeCoderPingCommand(program) {
|
|
44098
44240
|
const command = program.command('ping');
|
|
44099
44241
|
command.description(_spaceTrim.spaceTrim(`
|
|
44100
|
-
|
|
44242
|
+
Send one tiny dummy prompt to a harness and model to measure and warm them up
|
|
44101
44243
|
|
|
44102
44244
|
${PROMPT_RUNNER_DESCRIPTION}
|
|
44103
44245
|
|
|
44104
44246
|
Features:
|
|
44105
|
-
-
|
|
44106
|
-
-
|
|
44107
|
-
-
|
|
44108
|
-
-
|
|
44247
|
+
- Verifies that the selected harness, model, thinking level and authentication really work
|
|
44248
|
+
- Reports the answer of the harness, the response time and the reported usage
|
|
44249
|
+
- Starts the hourly/weekly quota window before you need it, so it is already refreshing when you do
|
|
44250
|
+
- Leaves the project exactly as it was — nothing is read, written, changed or committed
|
|
44251
|
+
- Use --no-ui to stream the raw harness output instead of only the compact result
|
|
44109
44252
|
`));
|
|
44110
44253
|
addPromptRunnerSelectionOptions(command);
|
|
44111
44254
|
addPromptRunnerRuntimeOptions(command);
|
|
44112
44255
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
44113
|
-
const
|
|
44114
|
-
|
|
44115
|
-
|
|
44116
|
-
|
|
44117
|
-
|
|
44118
|
-
|
|
44119
|
-
|
|
44120
|
-
|
|
44121
|
-
|
|
44122
|
-
|
|
44123
|
-
|
|
44124
|
-
const { runCoderPing } = await Promise.resolve().then(function () { return runCoderPing$1; });
|
|
44125
|
-
const pingResult = await runCoderPing({
|
|
44126
|
-
agentName,
|
|
44127
|
-
model: normalizedOptions.model,
|
|
44128
|
-
thinkingLevel: normalizedOptions.thinkingLevel,
|
|
44129
|
-
isUiDisabled: normalizedOptions.noUi,
|
|
44130
|
-
isCreditsAllowed: normalizedOptions.allowCredits,
|
|
44256
|
+
const runnerOptions = normalizePromptRunnerSelectionCliOptions(cliOptions, { isAgentRequired: true });
|
|
44257
|
+
await $ensureHarnessInstallations([runnerOptions.agentName]);
|
|
44258
|
+
// Note: Import the ping dynamically to avoid loading heavy dependencies until needed
|
|
44259
|
+
const { pingCoderHarness } = await Promise.resolve().then(function () { return pingCoderHarness$1; });
|
|
44260
|
+
const { printCoderPingResult } = await Promise.resolve().then(function () { return printCoderPingResult$1; });
|
|
44261
|
+
const result = await pingCoderHarness({
|
|
44262
|
+
agentName: runnerOptions.agentName,
|
|
44263
|
+
model: runnerOptions.model,
|
|
44264
|
+
thinkingLevel: runnerOptions.thinkingLevel,
|
|
44265
|
+
allowCredits: runnerOptions.allowCredits,
|
|
44266
|
+
shouldPrintLiveOutput: runnerOptions.noUi,
|
|
44131
44267
|
});
|
|
44132
|
-
printCoderPingResult(
|
|
44268
|
+
printCoderPingResult(result);
|
|
44133
44269
|
}));
|
|
44134
44270
|
}
|
|
44135
|
-
/**
|
|
44136
|
-
* Prints the result and duration of one completed coder ping.
|
|
44137
|
-
*/
|
|
44138
|
-
function printCoderPingResult(pingResult) {
|
|
44139
|
-
console.info(_spaceTrim.spaceTrim(`
|
|
44140
|
-
Result: ${pingResult.result}
|
|
44141
|
-
Time: ${pingResult.elapsedTimeMs.toFixed(0)} ms
|
|
44142
|
-
`));
|
|
44143
|
-
}
|
|
44144
44271
|
// Note: [🟡] Code for CLI command [ping](src/cli/cli-commands/coder/ping.ts) should never be published outside of `@promptbook/cli`
|
|
44145
44272
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44146
44273
|
|
|
@@ -44511,25 +44638,31 @@
|
|
|
44511
44638
|
*/
|
|
44512
44639
|
function $initializeCoderVerifyCommand(program) {
|
|
44513
44640
|
const command = program.command('verify');
|
|
44514
|
-
command.description(_spaceTrim.spaceTrim(`
|
|
44515
|
-
|
|
44641
|
+
command.description(_spaceTrim.spaceTrim((block) => `
|
|
44642
|
+
Interactive verification helper for completed prompts
|
|
44516
44643
|
|
|
44517
|
-
|
|
44518
|
-
|
|
44519
|
-
|
|
44520
|
-
|
|
44521
|
-
|
|
44522
|
-
|
|
44523
|
-
|
|
44524
|
-
|
|
44644
|
+
Features:
|
|
44645
|
+
- Displays list of prompt files with status counts
|
|
44646
|
+
- Guides through verification of completed prompts marked [x]
|
|
44647
|
+
- Archives verified prompt files to prompts/done/ directory
|
|
44648
|
+
- Auto-appends repair prompts for incomplete work
|
|
44649
|
+
- Processes files with all-done prompts first
|
|
44650
|
+
- Supports ignoring matching prompt candidates for one verification run
|
|
44651
|
+
|
|
44652
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
44653
|
+
|
|
44654
|
+
Note: The git synchronization is applied around each single verification, not once per run.
|
|
44655
|
+
`));
|
|
44525
44656
|
command.option('--reverse', 'Process prompt files in reverse order', false);
|
|
44526
44657
|
command.option('--ignore <candidate-text>', 'Ignore prompt files whose filename or first prompt line contains the given text (repeatable)', collectStringOption, []);
|
|
44658
|
+
addCoderGitSyncOptions(command);
|
|
44527
44659
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
44528
44660
|
const { reverse, ignore } = cliOptions;
|
|
44661
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
44529
44662
|
// Note: Import the main function dynamically to avoid loading heavy dependencies until needed
|
|
44530
44663
|
const { verifyPrompts } = await Promise.resolve().then(function () { return verifyPrompts$1; });
|
|
44531
44664
|
try {
|
|
44532
|
-
await verifyPrompts({ reverse, ignore });
|
|
44665
|
+
await verifyPrompts({ reverse, ignore, gitSync });
|
|
44533
44666
|
}
|
|
44534
44667
|
catch (error) {
|
|
44535
44668
|
console.error(colors__default["default"].bgRed('Prompt verification failed:'), error);
|
|
@@ -44557,8 +44690,8 @@
|
|
|
44557
44690
|
* - add: Add one ready-to-run prompt file to the queue
|
|
44558
44691
|
* - generate-boilerplates: Generate prompt boilerplate files
|
|
44559
44692
|
* - find-refactor-candidates: Find files that need refactoring
|
|
44560
|
-
* - ping: Test one harness and model connection with a disposable task
|
|
44561
44693
|
* - run: Run coding prompts with AI agents
|
|
44694
|
+
* - ping: Test one harness and model with a tiny dummy prompt
|
|
44562
44695
|
* - verify: Verify completed prompts
|
|
44563
44696
|
* - find-fresh-emoji-tags: Find unused emoji tags
|
|
44564
44697
|
*
|
|
@@ -44577,8 +44710,8 @@
|
|
|
44577
44710
|
- generate-boilerplates: Generate prompt boilerplate files
|
|
44578
44711
|
- find-refactor-candidates: Find files that need refactoring
|
|
44579
44712
|
- find-unwritten: List prompt sections that still need to be authored
|
|
44580
|
-
- ping: Test one harness and model connection with a disposable task
|
|
44581
44713
|
- run: Run coding prompts with AI agents
|
|
44714
|
+
- ping: Test the connection, response time and quota of one harness and model
|
|
44582
44715
|
- server: Start a long-running coder server with a kanban web UI
|
|
44583
44716
|
- verify: Verify completed prompts
|
|
44584
44717
|
- find-fresh-emoji-tags: Find unused emoji tags
|
|
@@ -44589,8 +44722,8 @@
|
|
|
44589
44722
|
$initializeCoderGenerateBoilerplatesCommand(coderCommand);
|
|
44590
44723
|
$initializeCoderFindRefactorCandidatesCommand(coderCommand);
|
|
44591
44724
|
$initializeCoderFindUnwrittenCommand(coderCommand);
|
|
44592
|
-
$initializeCoderPingCommand(coderCommand);
|
|
44593
44725
|
$initializeCoderRunCommand(coderCommand);
|
|
44726
|
+
$initializeCoderPingCommand(coderCommand);
|
|
44594
44727
|
$initializeCoderServerCommand(coderCommand);
|
|
44595
44728
|
$initializeCoderVerifyCommand(coderCommand);
|
|
44596
44729
|
$initializeCoderFindFreshEmojiTagCommand(coderCommand);
|
|
@@ -45424,6 +45557,14 @@
|
|
|
45424
45557
|
// Note: [🟢] Code for Node file-cache storage [FileCacheStorage](src/storage/file-cache-storage/FileCacheStorage.ts) should never be published into packages that could be imported into browser environment
|
|
45425
45558
|
// TODO: [🌗] Maybe some checkers, not all valid JSONs are desired and valid values
|
|
45426
45559
|
|
|
45560
|
+
/**
|
|
45561
|
+
* Loads the Socket.io client (`socket.io-client`) on demand
|
|
45562
|
+
*
|
|
45563
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
45564
|
+
*
|
|
45565
|
+
* @private internal utility of `createRemoteClient`
|
|
45566
|
+
*/
|
|
45567
|
+
const loadSocketIoClientModule = createLazyModuleLoader(() => import('socket.io-client'));
|
|
45427
45568
|
/**
|
|
45428
45569
|
* Creates a connection to the remote proxy server.
|
|
45429
45570
|
*
|
|
@@ -45452,8 +45593,9 @@
|
|
|
45452
45593
|
|
|
45453
45594
|
`));
|
|
45454
45595
|
}
|
|
45596
|
+
const { io } = await loadSocketIoClientModule();
|
|
45455
45597
|
return new Promise((resolve, reject) => {
|
|
45456
|
-
const socket =
|
|
45598
|
+
const socket = io(remoteServerUrl, {
|
|
45457
45599
|
retries: CONNECTION_RETRIES_LIMIT,
|
|
45458
45600
|
timeout: CONNECTION_TIMEOUT_MS,
|
|
45459
45601
|
path: '/socket.io',
|
|
@@ -46119,7 +46261,8 @@
|
|
|
46119
46261
|
You will be logged in to ${remoteServerUrl}
|
|
46120
46262
|
If you don't have an account, it will be created automatically.
|
|
46121
46263
|
`)));
|
|
46122
|
-
const {
|
|
46264
|
+
const { default: prompts } = await loadPromptsModule();
|
|
46265
|
+
const { username, password } = await prompts([
|
|
46123
46266
|
{
|
|
46124
46267
|
type: 'text',
|
|
46125
46268
|
name: 'username',
|
|
@@ -46494,6 +46637,15 @@
|
|
|
46494
46637
|
// TODO: Implement non-interactive login
|
|
46495
46638
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
46496
46639
|
|
|
46640
|
+
/**
|
|
46641
|
+
* Loads the ZIP archive library (`jszip`) on demand
|
|
46642
|
+
*
|
|
46643
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
46644
|
+
*
|
|
46645
|
+
* @private internal utility of `loadArchive` and `saveArchive`
|
|
46646
|
+
*/
|
|
46647
|
+
const loadJsZipModule = createLazyModuleLoader(() => import('jszip'));
|
|
46648
|
+
|
|
46497
46649
|
/**
|
|
46498
46650
|
* Loads the books from the archive file with `.bookc` extension
|
|
46499
46651
|
*
|
|
@@ -46508,7 +46660,8 @@
|
|
|
46508
46660
|
throw new UnexpectedError(`Archive file must have '.bookc' extension`);
|
|
46509
46661
|
}
|
|
46510
46662
|
const data = await fs.readFile(filePath);
|
|
46511
|
-
const
|
|
46663
|
+
const { default: JSZip } = await loadJsZipModule();
|
|
46664
|
+
const archive = await JSZip.loadAsync(data);
|
|
46512
46665
|
const indexFile = archive.file('index.book.json');
|
|
46513
46666
|
if (!indexFile) {
|
|
46514
46667
|
throw new UnexpectedError(`Archive does not contain 'index.book.json' file`);
|
|
@@ -50571,7 +50724,23 @@
|
|
|
50571
50724
|
});
|
|
50572
50725
|
}
|
|
50573
50726
|
|
|
50574
|
-
|
|
50727
|
+
/**
|
|
50728
|
+
* Loads `jsdom` on demand
|
|
50729
|
+
*
|
|
50730
|
+
* Note: [🐌] `jsdom` is by far the heaviest dependency of Promptbook, loading it eagerly would slow down every single
|
|
50731
|
+
* run of the `ptbk` CLI utility even when no website is scraped
|
|
50732
|
+
*
|
|
50733
|
+
* @private internal utility of `WebsiteScraper`
|
|
50734
|
+
*/
|
|
50735
|
+
const loadJsdomModule = createLazyModuleLoader(() => import('jsdom'));
|
|
50736
|
+
/**
|
|
50737
|
+
* Loads `@mozilla/readability` on demand
|
|
50738
|
+
*
|
|
50739
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
50740
|
+
*
|
|
50741
|
+
* @private internal utility of `WebsiteScraper`
|
|
50742
|
+
*/
|
|
50743
|
+
const loadReadabilityModule = createLazyModuleLoader(() => import('@mozilla/readability'));
|
|
50575
50744
|
/**
|
|
50576
50745
|
* Scraper for websites
|
|
50577
50746
|
*
|
|
@@ -50607,14 +50776,15 @@
|
|
|
50607
50776
|
if (this.tools.fs === undefined) {
|
|
50608
50777
|
throw new EnvironmentMismatchError('Can not scrape websites without filesystem tools');
|
|
50609
50778
|
}
|
|
50610
|
-
const
|
|
50779
|
+
const [{ JSDOM }, { Readability }] = await Promise.all([loadJsdomModule(), loadReadabilityModule()]);
|
|
50780
|
+
const jsdom = new JSDOM(await source.asText(), {
|
|
50611
50781
|
url: source.url,
|
|
50612
50782
|
});
|
|
50613
|
-
const reader = new
|
|
50783
|
+
const reader = new Readability(jsdom.window.document);
|
|
50614
50784
|
const article = reader.parse();
|
|
50615
50785
|
// console.log(article);
|
|
50616
50786
|
// await forTime(10000);
|
|
50617
|
-
let html = (article === null || article === void 0 ? void 0 : article.content) || (article === null || article === void 0 ? void 0 : article.textContent) || jsdom
|
|
50787
|
+
let html = (article === null || article === void 0 ? void 0 : article.content) || (article === null || article === void 0 ? void 0 : article.textContent) || jsdom.window.document.body.innerHTML;
|
|
50618
50788
|
// Note: Unwrap html such as it is convertable by `markdownConverter`
|
|
50619
50789
|
for (let i = 0; i < 2; i++) {
|
|
50620
50790
|
html = html.replace(/<div\s*(?:id="readability-page-\d+"\s+class="page")?>(.*)<\/div>/is, '$1');
|
|
@@ -50647,7 +50817,7 @@
|
|
|
50647
50817
|
throw error;
|
|
50648
50818
|
}
|
|
50649
50819
|
}
|
|
50650
|
-
const markdown = this.showdownConverter.makeMarkdown(html, jsdom
|
|
50820
|
+
const markdown = this.showdownConverter.makeMarkdown(html, jsdom.window.document);
|
|
50651
50821
|
return { ...cacheFilehandler, markdown };
|
|
50652
50822
|
}
|
|
50653
50823
|
/**
|
|
@@ -54210,7 +54380,8 @@
|
|
|
54210
54380
|
for (const pipelineJson of collectionJson) {
|
|
54211
54381
|
validatePipeline(pipelineJson);
|
|
54212
54382
|
}
|
|
54213
|
-
const
|
|
54383
|
+
const { default: JSZip } = await loadJsZipModule();
|
|
54384
|
+
const archive = new JSZip();
|
|
54214
54385
|
const collectionJsonString = stringifyPipelineJson(collectionJson);
|
|
54215
54386
|
archive.file('index.book.json', collectionJsonString);
|
|
54216
54387
|
const data = await archive.generateAsync({ type: 'nodebuffer', streamFiles: true });
|
|
@@ -54838,7 +55009,8 @@
|
|
|
54838
55009
|
else {
|
|
54839
55010
|
console.info(colors__default["default"].gray(`---`));
|
|
54840
55011
|
}
|
|
54841
|
-
const
|
|
55012
|
+
const { default: prompts } = await loadPromptsModule();
|
|
55013
|
+
const response = await prompts({
|
|
54842
55014
|
type: 'text',
|
|
54843
55015
|
name: 'userMessage',
|
|
54844
55016
|
message: 'User message',
|
|
@@ -55145,7 +55317,8 @@
|
|
|
55145
55317
|
if (pipelineSource) {
|
|
55146
55318
|
return pipelineSource;
|
|
55147
55319
|
}
|
|
55148
|
-
const
|
|
55320
|
+
const { default: prompts } = await loadPromptsModule();
|
|
55321
|
+
const response = await prompts({
|
|
55149
55322
|
type: 'text',
|
|
55150
55323
|
name: 'pipelineSource',
|
|
55151
55324
|
message: '',
|
|
@@ -55232,7 +55405,8 @@
|
|
|
55232
55405
|
console.error(colors__default["default"].red(createRunMissingInputParametersMessage(pipeline, inputParameters, questions)));
|
|
55233
55406
|
return process.exit(1);
|
|
55234
55407
|
}
|
|
55235
|
-
const
|
|
55408
|
+
const { default: prompts } = await loadPromptsModule();
|
|
55409
|
+
const response = await prompts(questions);
|
|
55236
55410
|
// <- TODO: [🧠][🍼] Change behavior according to the formfactor
|
|
55237
55411
|
return { ...inputParameters, ...response };
|
|
55238
55412
|
// <- TODO: Maybe do some validation of the response (and --json argument which is passed)
|
|
@@ -58137,6 +58311,14 @@
|
|
|
58137
58311
|
fullname: 'Anthropic Claude',
|
|
58138
58312
|
color: '#d97706',
|
|
58139
58313
|
};
|
|
58314
|
+
/**
|
|
58315
|
+
* Loads the Anthropic Claude SDK (`@anthropic-ai/sdk`) on demand
|
|
58316
|
+
*
|
|
58317
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
58318
|
+
*
|
|
58319
|
+
* @private internal utility of `AnthropicClaudeExecutionTools`
|
|
58320
|
+
*/
|
|
58321
|
+
const loadAnthropicClaudeModule = createLazyModuleLoader(() => import('@anthropic-ai/sdk'));
|
|
58140
58322
|
/**
|
|
58141
58323
|
* Execution Tools for calling Anthropic Claude API.
|
|
58142
58324
|
*
|
|
@@ -58174,7 +58356,8 @@
|
|
|
58174
58356
|
const anthropicOptions = { ...this.options };
|
|
58175
58357
|
delete anthropicOptions.isVerbose;
|
|
58176
58358
|
delete anthropicOptions.isProxied;
|
|
58177
|
-
|
|
58359
|
+
const { Anthropic } = await loadAnthropicClaudeModule();
|
|
58360
|
+
this.client = new Anthropic(anthropicOptions);
|
|
58178
58361
|
}
|
|
58179
58362
|
return this.client;
|
|
58180
58363
|
}
|
|
@@ -58437,6 +58620,14 @@
|
|
|
58437
58620
|
fullname: 'Azure OpenAI',
|
|
58438
58621
|
color: '#0078d4',
|
|
58439
58622
|
};
|
|
58623
|
+
/**
|
|
58624
|
+
* Loads the Azure OpenAI SDK (`@azure/openai`) on demand
|
|
58625
|
+
*
|
|
58626
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
58627
|
+
*
|
|
58628
|
+
* @private internal utility of `AzureOpenAiExecutionTools`
|
|
58629
|
+
*/
|
|
58630
|
+
const loadAzureOpenAiModule = createLazyModuleLoader(() => import('@azure/openai'));
|
|
58440
58631
|
/**
|
|
58441
58632
|
* Execution Tools for calling Azure OpenAI API.
|
|
58442
58633
|
*
|
|
@@ -58470,7 +58661,8 @@
|
|
|
58470
58661
|
}
|
|
58471
58662
|
async getClient() {
|
|
58472
58663
|
if (this.client === null) {
|
|
58473
|
-
|
|
58664
|
+
const { AzureKeyCredential, OpenAIClient } = await loadAzureOpenAiModule();
|
|
58665
|
+
this.client = new OpenAIClient(`https://${this.options.resourceName}.openai.azure.com/`, new AzureKeyCredential(this.options.apiKey));
|
|
58474
58666
|
}
|
|
58475
58667
|
return this.client;
|
|
58476
58668
|
}
|
|
@@ -60279,6 +60471,14 @@
|
|
|
60279
60471
|
}
|
|
60280
60472
|
}
|
|
60281
60473
|
|
|
60474
|
+
/**
|
|
60475
|
+
* Loads the OpenAI SDK (`openai`) on demand
|
|
60476
|
+
*
|
|
60477
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
60478
|
+
*
|
|
60479
|
+
* @private internal utility of `OpenAiCompatibleRequestManager`
|
|
60480
|
+
*/
|
|
60481
|
+
const loadOpenAiModule = createLazyModuleLoader(() => import('openai'));
|
|
60282
60482
|
/**
|
|
60283
60483
|
* Manages OpenAI-compatible client creation plus shared retry and rate-limit behavior.
|
|
60284
60484
|
*
|
|
@@ -60305,7 +60505,8 @@
|
|
|
60305
60505
|
timeout: API_REQUEST_TIMEOUT,
|
|
60306
60506
|
maxRetries: CONNECTION_RETRIES_LIMIT,
|
|
60307
60507
|
};
|
|
60308
|
-
|
|
60508
|
+
const { default: OpenAI } = await loadOpenAiModule();
|
|
60509
|
+
this.client = new OpenAI(enhancedOptions);
|
|
60309
60510
|
}
|
|
60310
60511
|
return this.client;
|
|
60311
60512
|
}
|
|
@@ -68018,8 +68219,9 @@
|
|
|
68018
68219
|
if (options.isVerbose) {
|
|
68019
68220
|
console.info(colors__default["default"].gray('Type "exit" or "quit" to end the chat.'));
|
|
68020
68221
|
}
|
|
68222
|
+
const { default: prompts } = await loadPromptsModule();
|
|
68021
68223
|
while (true) {
|
|
68022
|
-
const response = await
|
|
68224
|
+
const response = await prompts({
|
|
68023
68225
|
type: 'text',
|
|
68024
68226
|
name: 'userMessage',
|
|
68025
68227
|
message: 'User message',
|
|
@@ -69231,6 +69433,16 @@
|
|
|
69231
69433
|
}
|
|
69232
69434
|
}
|
|
69233
69435
|
|
|
69436
|
+
/**
|
|
69437
|
+
* Loads the OpenAI AgentKit SDK (`@openai/agents`) on demand
|
|
69438
|
+
*
|
|
69439
|
+
* Note: [🐌] The AgentKit SDK is one of the heaviest dependencies of Promptbook, loading it eagerly would slow down
|
|
69440
|
+
* every single run of the `ptbk` CLI utility even when no AgentKit agent is used
|
|
69441
|
+
*
|
|
69442
|
+
* @private internal utility of `@promptbook/openai`
|
|
69443
|
+
*/
|
|
69444
|
+
const loadOpenAiAgentsModule = createLazyModuleLoader(() => import('@openai/agents'));
|
|
69445
|
+
|
|
69234
69446
|
/**
|
|
69235
69447
|
* Constant for default model used for nested DeepSearch tool invocations.
|
|
69236
69448
|
*/
|
|
@@ -69284,11 +69496,12 @@
|
|
|
69284
69496
|
/**
|
|
69285
69497
|
* Builds the tool list for AgentKit, including hosted file search when applicable.
|
|
69286
69498
|
*/
|
|
69287
|
-
buildAgentKitTools(options) {
|
|
69499
|
+
async buildAgentKitTools(options) {
|
|
69288
69500
|
const { tools, vectorStoreId } = options;
|
|
69501
|
+
const { fileSearchTool, tool: agentKitTool } = await loadOpenAiAgentsModule();
|
|
69289
69502
|
const agentKitTools = [];
|
|
69290
69503
|
if (vectorStoreId) {
|
|
69291
|
-
agentKitTools.push(
|
|
69504
|
+
agentKitTools.push(fileSearchTool(vectorStoreId));
|
|
69292
69505
|
}
|
|
69293
69506
|
if (!tools || tools.length === 0) {
|
|
69294
69507
|
return agentKitTools;
|
|
@@ -69296,11 +69509,11 @@
|
|
|
69296
69509
|
let scriptTools = null;
|
|
69297
69510
|
for (const toolDefinition of tools) {
|
|
69298
69511
|
if (this.isDeepSearchToolDefinition(toolDefinition)) {
|
|
69299
|
-
agentKitTools.push(this.createDeepSearchAgentKitTool(toolDefinition));
|
|
69512
|
+
agentKitTools.push(await this.createDeepSearchAgentKitTool(toolDefinition));
|
|
69300
69513
|
continue;
|
|
69301
69514
|
}
|
|
69302
69515
|
scriptTools !== null && scriptTools !== void 0 ? scriptTools : (scriptTools = this.resolveScriptTools());
|
|
69303
|
-
agentKitTools.push(
|
|
69516
|
+
agentKitTools.push(agentKitTool({
|
|
69304
69517
|
name: toolDefinition.name,
|
|
69305
69518
|
description: toolDefinition.description,
|
|
69306
69519
|
parameters: this.normalizeAgentKitToolParameters(toolDefinition.parameters),
|
|
@@ -69507,12 +69720,13 @@
|
|
|
69507
69720
|
/**
|
|
69508
69721
|
* Creates the native Agent SDK tool used for `USE DEEPSEARCH`.
|
|
69509
69722
|
*/
|
|
69510
|
-
createDeepSearchAgentKitTool(toolDefinition) {
|
|
69511
|
-
const
|
|
69723
|
+
async createDeepSearchAgentKitTool(toolDefinition) {
|
|
69724
|
+
const { Agent: AgentFromKit, webSearchTool } = await loadOpenAiAgentsModule();
|
|
69725
|
+
const deepSearchAgent = new AgentFromKit({
|
|
69512
69726
|
name: 'DeepSearch',
|
|
69513
69727
|
model: DEFAULT_DEEP_SEARCH_MODEL_NAME,
|
|
69514
69728
|
instructions: this.createDeepSearchAgentInstructions(toolDefinition.description),
|
|
69515
|
-
tools: [
|
|
69729
|
+
tools: [webSearchTool({ searchContextSize: 'high' })],
|
|
69516
69730
|
});
|
|
69517
69731
|
return deepSearchAgent.asTool({
|
|
69518
69732
|
toolName: toolDefinition.name,
|
|
@@ -69721,8 +69935,9 @@
|
|
|
69721
69935
|
vectorStoreId,
|
|
69722
69936
|
});
|
|
69723
69937
|
}
|
|
69724
|
-
const
|
|
69725
|
-
const
|
|
69938
|
+
const { Agent: AgentFromKit } = await loadOpenAiAgentsModule();
|
|
69939
|
+
const agentKitTools = await this.buildAgentKitTools({ tools, vectorStoreId });
|
|
69940
|
+
const openAiAgentKitAgent = new AgentFromKit({
|
|
69726
69941
|
name,
|
|
69727
69942
|
model: this.agentKitModelName,
|
|
69728
69943
|
instructions: instructions || 'You are a helpful assistant.',
|
|
@@ -69767,7 +69982,8 @@
|
|
|
69767
69982
|
agentName: agentForRun.name,
|
|
69768
69983
|
input: inputItems,
|
|
69769
69984
|
};
|
|
69770
|
-
const
|
|
69985
|
+
const { run } = await loadOpenAiAgentsModule();
|
|
69986
|
+
const streamResult = await run(agentForRun, inputItems, {
|
|
69771
69987
|
stream: true,
|
|
69772
69988
|
maxTurns: 200,
|
|
69773
69989
|
context: {
|
|
@@ -69909,11 +70125,12 @@
|
|
|
69909
70125
|
* Ensures the AgentKit SDK is wired to the OpenAI client and API key.
|
|
69910
70126
|
*/
|
|
69911
70127
|
async ensureAgentKitDefaults() {
|
|
70128
|
+
const { setDefaultOpenAIClient, setDefaultOpenAIKey } = await loadOpenAiAgentsModule();
|
|
69912
70129
|
const client = await this.getClient();
|
|
69913
|
-
|
|
70130
|
+
setDefaultOpenAIClient(client);
|
|
69914
70131
|
const apiKey = this.agentKitOptions.apiKey;
|
|
69915
70132
|
if (apiKey && typeof apiKey === 'string') {
|
|
69916
|
-
|
|
70133
|
+
setDefaultOpenAIKey(apiKey);
|
|
69917
70134
|
}
|
|
69918
70135
|
}
|
|
69919
70136
|
/**
|
|
@@ -72241,6 +72458,66 @@
|
|
|
72241
72458
|
RemoteAgent: RemoteAgent
|
|
72242
72459
|
});
|
|
72243
72460
|
|
|
72461
|
+
/**
|
|
72462
|
+
* Git synchronization which leaves the repository completely untouched.
|
|
72463
|
+
*
|
|
72464
|
+
* Note: This is the default for every command and helper which supports the git synchronization.
|
|
72465
|
+
*/
|
|
72466
|
+
const DISABLED_CODER_GIT_SYNC_OPTIONS = Object.freeze({
|
|
72467
|
+
isCommitEnabled: false,
|
|
72468
|
+
isAutoPushEnabled: false,
|
|
72469
|
+
isAutoPullEnabled: false,
|
|
72470
|
+
});
|
|
72471
|
+
/**
|
|
72472
|
+
* Pulls the latest repository changes before a `ptbk coder` command changes the project.
|
|
72473
|
+
*/
|
|
72474
|
+
async function $pullCoderChanges(options) {
|
|
72475
|
+
const { gitSync, projectPath = process.cwd() } = options;
|
|
72476
|
+
if (!gitSync.isAutoPullEnabled) {
|
|
72477
|
+
return;
|
|
72478
|
+
}
|
|
72479
|
+
console.info(colors__default["default"].gray('Pulling the latest changes from the remote repository...'));
|
|
72480
|
+
await pullLatestChanges(projectPath);
|
|
72481
|
+
}
|
|
72482
|
+
/**
|
|
72483
|
+
* Commits - and when requested also pushes - the changes one `ptbk coder` command has just made.
|
|
72484
|
+
*
|
|
72485
|
+
* Note: A repository without any change is left alone instead of creating an empty commit.
|
|
72486
|
+
*/
|
|
72487
|
+
async function $commitCoderChanges(options) {
|
|
72488
|
+
const { gitSync, commitMessage, projectPath = process.cwd() } = options;
|
|
72489
|
+
if (!gitSync.isCommitEnabled) {
|
|
72490
|
+
return;
|
|
72491
|
+
}
|
|
72492
|
+
if (!(await hasChangesToCommit(projectPath))) {
|
|
72493
|
+
console.info(colors__default["default"].gray('Nothing to commit, the working tree is clean'));
|
|
72494
|
+
return;
|
|
72495
|
+
}
|
|
72496
|
+
await commitChanges(commitMessage, {
|
|
72497
|
+
projectPath,
|
|
72498
|
+
autoPush: gitSync.isAutoPushEnabled,
|
|
72499
|
+
});
|
|
72500
|
+
console.info(colors__default["default"].green(`✓ ${gitSync.isAutoPushEnabled ? 'Committed and pushed' : 'Committed'}: ${commitMessage}`));
|
|
72501
|
+
}
|
|
72502
|
+
/**
|
|
72503
|
+
* Checks whether the repository holds any change which can be committed.
|
|
72504
|
+
*/
|
|
72505
|
+
async function hasChangesToCommit(projectPath) {
|
|
72506
|
+
const gitStatus = await runGitCommand({
|
|
72507
|
+
command: 'git status --porcelain',
|
|
72508
|
+
cwd: projectPath,
|
|
72509
|
+
isVerbose: false,
|
|
72510
|
+
});
|
|
72511
|
+
return gitStatus.trim() !== '';
|
|
72512
|
+
}
|
|
72513
|
+
|
|
72514
|
+
var coderGitSync = /*#__PURE__*/Object.freeze({
|
|
72515
|
+
__proto__: null,
|
|
72516
|
+
DISABLED_CODER_GIT_SYNC_OPTIONS: DISABLED_CODER_GIT_SYNC_OPTIONS,
|
|
72517
|
+
$pullCoderChanges: $pullCoderChanges,
|
|
72518
|
+
$commitCoderChanges: $commitCoderChanges
|
|
72519
|
+
});
|
|
72520
|
+
|
|
72244
72521
|
/**
|
|
72245
72522
|
* Calculates the next available prompt numbering sequence for a month.
|
|
72246
72523
|
*/
|
|
@@ -72715,6 +72992,31 @@
|
|
|
72715
72992
|
}
|
|
72716
72993
|
// Note: [🟡] Code for repository script [normalizeRefactorCandidatePath](scripts/find-refactor-candidates/normalizeRefactorCandidatePath.ts) should never be published outside of `@promptbook/cli`
|
|
72717
72994
|
|
|
72995
|
+
/**
|
|
72996
|
+
* The TypeScript compiler API once it was loaded by `analyzeSourceFileForRefactorCandidate`
|
|
72997
|
+
*
|
|
72998
|
+
* Note: [🐌] `typescript` is a heavy package, it is loaded on demand so that it does not slow down every single run
|
|
72999
|
+
* of the `ptbk` CLI utility
|
|
73000
|
+
*
|
|
73001
|
+
* @private variable of analyzeSourceFileForRefactorCandidate
|
|
73002
|
+
*/
|
|
73003
|
+
let loadedTypescriptModule = null;
|
|
73004
|
+
/**
|
|
73005
|
+
* Returns the TypeScript compiler API which was already loaded for the structural analysis.
|
|
73006
|
+
*
|
|
73007
|
+
* @private function of analyzeSourceFileForRefactorCandidate
|
|
73008
|
+
*/
|
|
73009
|
+
function getLoadedTypescriptModule() {
|
|
73010
|
+
if (loadedTypescriptModule === null) {
|
|
73011
|
+
throw new UnexpectedError(spaceTrim(`
|
|
73012
|
+
The \`typescript\` module was not loaded yet.
|
|
73013
|
+
|
|
73014
|
+
Structural analysis helpers must be called only from \`analyzeSourceFileForRefactorCandidate\` which
|
|
73015
|
+
loads \`typescript\` lazily.
|
|
73016
|
+
`));
|
|
73017
|
+
}
|
|
73018
|
+
return loadedTypescriptModule;
|
|
73019
|
+
}
|
|
72718
73020
|
/**
|
|
72719
73021
|
* Resolves whether a source file should produce a refactor candidate entry.
|
|
72720
73022
|
*
|
|
@@ -72740,6 +73042,7 @@
|
|
|
72740
73042
|
}
|
|
72741
73043
|
}
|
|
72742
73044
|
if (STRUCTURAL_ANALYSIS_EXTENSIONS.includes(extension)) {
|
|
73045
|
+
loadedTypescriptModule !== null && loadedTypescriptModule !== void 0 ? loadedTypescriptModule : (loadedTypescriptModule = await getTypescriptModule());
|
|
72743
73046
|
const structureSummary = summarizeSourceFileStructure(content, extension, filePath);
|
|
72744
73047
|
if (structureSummary.entityCount > heuristics.maxEntityCountPerFile) {
|
|
72745
73048
|
reasons.push(`entities ${structureSummary.entityCount}/${heuristics.maxEntityCountPerFile}`);
|
|
@@ -72799,8 +73102,9 @@
|
|
|
72799
73102
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72800
73103
|
*/
|
|
72801
73104
|
function summarizeSourceFileStructure(content, extension, filePath) {
|
|
73105
|
+
const ts = getLoadedTypescriptModule();
|
|
72802
73106
|
const scriptKind = getScriptKindForExtension(extension);
|
|
72803
|
-
const sourceFile =
|
|
73107
|
+
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKind);
|
|
72804
73108
|
return {
|
|
72805
73109
|
entityCount: countEntitiesInSourceFile(sourceFile),
|
|
72806
73110
|
...summarizeFunctionsInSourceFile(sourceFile),
|
|
@@ -72812,25 +73116,26 @@
|
|
|
72812
73116
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72813
73117
|
*/
|
|
72814
73118
|
function countEntitiesInSourceFile(sourceFile) {
|
|
73119
|
+
const ts = getLoadedTypescriptModule();
|
|
72815
73120
|
let count = 0;
|
|
72816
73121
|
// Only count top-level declarations to avoid inflating with members or nested scopes.
|
|
72817
73122
|
for (const statement of sourceFile.statements) {
|
|
72818
|
-
if (
|
|
72819
|
-
|
|
72820
|
-
|
|
72821
|
-
|
|
72822
|
-
|
|
72823
|
-
|
|
73123
|
+
if (ts.isFunctionDeclaration(statement) ||
|
|
73124
|
+
ts.isClassDeclaration(statement) ||
|
|
73125
|
+
ts.isInterfaceDeclaration(statement) ||
|
|
73126
|
+
ts.isTypeAliasDeclaration(statement) ||
|
|
73127
|
+
ts.isEnumDeclaration(statement) ||
|
|
73128
|
+
ts.isModuleDeclaration(statement)) {
|
|
72824
73129
|
count += 1;
|
|
72825
73130
|
continue;
|
|
72826
73131
|
}
|
|
72827
|
-
if (
|
|
73132
|
+
if (ts.isVariableStatement(statement)) {
|
|
72828
73133
|
for (const declaration of statement.declarationList.declarations) {
|
|
72829
73134
|
const initializer = declaration.initializer;
|
|
72830
73135
|
if (initializer &&
|
|
72831
|
-
(
|
|
72832
|
-
|
|
72833
|
-
|
|
73136
|
+
(ts.isArrowFunction(initializer) ||
|
|
73137
|
+
ts.isFunctionExpression(initializer) ||
|
|
73138
|
+
ts.isClassExpression(initializer))) {
|
|
72834
73139
|
count += 1;
|
|
72835
73140
|
}
|
|
72836
73141
|
}
|
|
@@ -72844,6 +73149,7 @@
|
|
|
72844
73149
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72845
73150
|
*/
|
|
72846
73151
|
function summarizeFunctionsInSourceFile(sourceFile) {
|
|
73152
|
+
const ts = getLoadedTypescriptModule();
|
|
72847
73153
|
let functionCount = 0;
|
|
72848
73154
|
let maxFunctionComplexity = 0;
|
|
72849
73155
|
let mostComplexFunctionName = null;
|
|
@@ -72856,7 +73162,7 @@
|
|
|
72856
73162
|
mostComplexFunctionName = getFunctionDisplayName(node);
|
|
72857
73163
|
}
|
|
72858
73164
|
}
|
|
72859
|
-
|
|
73165
|
+
ts.forEachChild(node, visitNode);
|
|
72860
73166
|
};
|
|
72861
73167
|
visitNode(sourceFile);
|
|
72862
73168
|
return {
|
|
@@ -72871,14 +73177,15 @@
|
|
|
72871
73177
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72872
73178
|
*/
|
|
72873
73179
|
function isCountedFunctionLikeDeclaration(node) {
|
|
72874
|
-
|
|
72875
|
-
|
|
72876
|
-
|
|
72877
|
-
|
|
72878
|
-
|
|
73180
|
+
const ts = getLoadedTypescriptModule();
|
|
73181
|
+
if (ts.isFunctionDeclaration(node) ||
|
|
73182
|
+
ts.isMethodDeclaration(node) ||
|
|
73183
|
+
ts.isConstructorDeclaration(node) ||
|
|
73184
|
+
ts.isGetAccessorDeclaration(node) ||
|
|
73185
|
+
ts.isSetAccessorDeclaration(node)) {
|
|
72879
73186
|
return true;
|
|
72880
73187
|
}
|
|
72881
|
-
if (
|
|
73188
|
+
if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) {
|
|
72882
73189
|
return isNamedFunctionExpression(node);
|
|
72883
73190
|
}
|
|
72884
73191
|
return false;
|
|
@@ -72889,8 +73196,9 @@
|
|
|
72889
73196
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72890
73197
|
*/
|
|
72891
73198
|
function isNamedFunctionExpression(node) {
|
|
73199
|
+
const ts = getLoadedTypescriptModule();
|
|
72892
73200
|
const parent = node.parent;
|
|
72893
|
-
return (
|
|
73201
|
+
return (ts.isVariableDeclaration(parent) || ts.isPropertyDeclaration(parent) || ts.isPropertyAssignment(parent));
|
|
72894
73202
|
}
|
|
72895
73203
|
/**
|
|
72896
73204
|
* Calculates a lightweight cyclomatic-complexity score for one function.
|
|
@@ -72901,6 +73209,7 @@
|
|
|
72901
73209
|
if (!functionNode.body) {
|
|
72902
73210
|
return 1;
|
|
72903
73211
|
}
|
|
73212
|
+
const ts = getLoadedTypescriptModule();
|
|
72904
73213
|
let complexity = 1;
|
|
72905
73214
|
const visitNode = (node) => {
|
|
72906
73215
|
if (node !== functionNode.body && isCountedFunctionLikeDeclaration(node)) {
|
|
@@ -72909,7 +73218,7 @@
|
|
|
72909
73218
|
if (isComplexityDecisionNode(node)) {
|
|
72910
73219
|
complexity += 1;
|
|
72911
73220
|
}
|
|
72912
|
-
|
|
73221
|
+
ts.forEachChild(node, visitNode);
|
|
72913
73222
|
};
|
|
72914
73223
|
visitNode(functionNode.body);
|
|
72915
73224
|
return complexity;
|
|
@@ -72920,22 +73229,23 @@
|
|
|
72920
73229
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72921
73230
|
*/
|
|
72922
73231
|
function isComplexityDecisionNode(node) {
|
|
72923
|
-
|
|
72924
|
-
|
|
72925
|
-
|
|
72926
|
-
|
|
72927
|
-
|
|
72928
|
-
|
|
72929
|
-
|
|
72930
|
-
|
|
72931
|
-
|
|
73232
|
+
const ts = getLoadedTypescriptModule();
|
|
73233
|
+
if (ts.isIfStatement(node) ||
|
|
73234
|
+
ts.isConditionalExpression(node) ||
|
|
73235
|
+
ts.isCatchClause(node) ||
|
|
73236
|
+
ts.isForStatement(node) ||
|
|
73237
|
+
ts.isForInStatement(node) ||
|
|
73238
|
+
ts.isForOfStatement(node) ||
|
|
73239
|
+
ts.isWhileStatement(node) ||
|
|
73240
|
+
ts.isDoStatement(node) ||
|
|
73241
|
+
ts.isCaseClause(node)) {
|
|
72932
73242
|
return true;
|
|
72933
73243
|
}
|
|
72934
|
-
if (
|
|
73244
|
+
if (ts.isBinaryExpression(node)) {
|
|
72935
73245
|
const operatorKind = node.operatorToken.kind;
|
|
72936
|
-
return (operatorKind ===
|
|
72937
|
-
operatorKind ===
|
|
72938
|
-
operatorKind ===
|
|
73246
|
+
return (operatorKind === ts.SyntaxKind.AmpersandAmpersandToken ||
|
|
73247
|
+
operatorKind === ts.SyntaxKind.BarBarToken ||
|
|
73248
|
+
operatorKind === ts.SyntaxKind.QuestionQuestionToken);
|
|
72939
73249
|
}
|
|
72940
73250
|
return false;
|
|
72941
73251
|
}
|
|
@@ -72945,27 +73255,28 @@
|
|
|
72945
73255
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72946
73256
|
*/
|
|
72947
73257
|
function getFunctionDisplayName(functionNode) {
|
|
72948
|
-
|
|
73258
|
+
const ts = getLoadedTypescriptModule();
|
|
73259
|
+
if (ts.isConstructorDeclaration(functionNode)) {
|
|
72949
73260
|
return 'constructor';
|
|
72950
73261
|
}
|
|
72951
|
-
if (
|
|
72952
|
-
|
|
72953
|
-
|
|
72954
|
-
|
|
73262
|
+
if (ts.isFunctionDeclaration(functionNode) ||
|
|
73263
|
+
ts.isMethodDeclaration(functionNode) ||
|
|
73264
|
+
ts.isGetAccessorDeclaration(functionNode) ||
|
|
73265
|
+
ts.isSetAccessorDeclaration(functionNode)) {
|
|
72955
73266
|
if (!functionNode.name) {
|
|
72956
73267
|
return null;
|
|
72957
73268
|
}
|
|
72958
73269
|
return getPropertyNameText(functionNode.name);
|
|
72959
73270
|
}
|
|
72960
|
-
if (
|
|
73271
|
+
if (ts.isArrowFunction(functionNode) || ts.isFunctionExpression(functionNode)) {
|
|
72961
73272
|
if (functionNode.name) {
|
|
72962
73273
|
return functionNode.name.text;
|
|
72963
73274
|
}
|
|
72964
73275
|
const parent = functionNode.parent;
|
|
72965
|
-
if (
|
|
73276
|
+
if (ts.isVariableDeclaration(parent)) {
|
|
72966
73277
|
return getBindingNameText(parent.name);
|
|
72967
73278
|
}
|
|
72968
|
-
if (
|
|
73279
|
+
if (ts.isPropertyDeclaration(parent) || ts.isPropertyAssignment(parent)) {
|
|
72969
73280
|
return getPropertyNameText(parent.name);
|
|
72970
73281
|
}
|
|
72971
73282
|
}
|
|
@@ -72977,7 +73288,8 @@
|
|
|
72977
73288
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72978
73289
|
*/
|
|
72979
73290
|
function getBindingNameText(name) {
|
|
72980
|
-
|
|
73291
|
+
const ts = getLoadedTypescriptModule();
|
|
73292
|
+
return ts.isIdentifier(name) ? name.text : null;
|
|
72981
73293
|
}
|
|
72982
73294
|
/**
|
|
72983
73295
|
* Resolves text for a property name while preserving computed names when necessary.
|
|
@@ -72985,7 +73297,8 @@
|
|
|
72985
73297
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72986
73298
|
*/
|
|
72987
73299
|
function getPropertyNameText(name) {
|
|
72988
|
-
|
|
73300
|
+
const ts = getLoadedTypescriptModule();
|
|
73301
|
+
if (ts.isIdentifier(name) || ts.isPrivateIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) {
|
|
72989
73302
|
return name.text;
|
|
72990
73303
|
}
|
|
72991
73304
|
return name.getText();
|
|
@@ -73007,16 +73320,17 @@
|
|
|
73007
73320
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
73008
73321
|
*/
|
|
73009
73322
|
function getScriptKindForExtension(extension) {
|
|
73323
|
+
const ts = getLoadedTypescriptModule();
|
|
73010
73324
|
if (extension === '.tsx') {
|
|
73011
|
-
return
|
|
73325
|
+
return ts.ScriptKind.TSX;
|
|
73012
73326
|
}
|
|
73013
73327
|
if (extension === '.jsx') {
|
|
73014
|
-
return
|
|
73328
|
+
return ts.ScriptKind.JSX;
|
|
73015
73329
|
}
|
|
73016
73330
|
if (extension === '.js') {
|
|
73017
|
-
return
|
|
73331
|
+
return ts.ScriptKind.JS;
|
|
73018
73332
|
}
|
|
73019
|
-
return
|
|
73333
|
+
return ts.ScriptKind.TS;
|
|
73020
73334
|
}
|
|
73021
73335
|
/**
|
|
73022
73336
|
* Normalizes an absolute path for consistent comparisons.
|
|
@@ -73866,63 +74180,240 @@
|
|
|
73866
74180
|
});
|
|
73867
74181
|
|
|
73868
74182
|
/**
|
|
73869
|
-
*
|
|
74183
|
+
* Builds a normalized temporary shell script path for prompt runners.
|
|
73870
74184
|
*/
|
|
73871
|
-
|
|
73872
|
-
|
|
74185
|
+
function buildTemporaryPromptScriptPath(options) {
|
|
74186
|
+
const sourceFileName = path.basename(options.sourceFileName);
|
|
74187
|
+
const scriptFileName = `${sourceFileName.replace(/\.[^.]+$/u, '')}${options.suffix || ''}.sh`;
|
|
74188
|
+
return resolvePromptbookTemporaryPath(options.projectPath, options.scriptDirectoryName, scriptFileName);
|
|
74189
|
+
}
|
|
73873
74190
|
|
|
73874
|
-
PERSONA You are a connectivity test agent. Perform only the tiny task requested by the user and answer concisely.
|
|
73875
|
-
`);
|
|
73876
74191
|
/**
|
|
73877
|
-
*
|
|
74192
|
+
* Marker the pinged harness is asked to prefix its answer with, so the reply can be recognized
|
|
74193
|
+
* in the raw runner output of every supported harness.
|
|
74194
|
+
*
|
|
74195
|
+
* Note: The marker must stay free of regular-expression metacharacters, because
|
|
74196
|
+
* `extractCoderPingAnswer` builds its pattern from it.
|
|
74197
|
+
*/
|
|
74198
|
+
const CODER_PING_ANSWER_MARKER = 'PTBK-CODER-PING-ANSWER';
|
|
74199
|
+
/**
|
|
74200
|
+
* First factor of the dummy multiplication the pinged harness is asked to compute.
|
|
74201
|
+
*/
|
|
74202
|
+
const CODER_PING_FIRST_FACTOR = 6;
|
|
74203
|
+
/**
|
|
74204
|
+
* Second factor of the dummy multiplication the pinged harness is asked to compute.
|
|
74205
|
+
*/
|
|
74206
|
+
const CODER_PING_SECOND_FACTOR = 7;
|
|
74207
|
+
/**
|
|
74208
|
+
* Answer a working harness and model returns for the dummy work of `ptbk coder ping`.
|
|
73878
74209
|
*/
|
|
73879
|
-
const
|
|
74210
|
+
const CODER_PING_EXPECTED_ANSWER = String(CODER_PING_FIRST_FACTOR * CODER_PING_SECOND_FACTOR);
|
|
73880
74211
|
/**
|
|
73881
|
-
*
|
|
74212
|
+
* Builds the dummy prompt sent by `ptbk coder ping`.
|
|
73882
74213
|
*
|
|
73883
|
-
* The
|
|
73884
|
-
*
|
|
73885
|
-
*
|
|
74214
|
+
* The work is intentionally the smallest possible one that still reaches the model: it spends a
|
|
74215
|
+
* negligible amount of the harness quota, it needs no tool and it explicitly forbids touching the
|
|
74216
|
+
* project, so a ping leaves the project exactly as it was.
|
|
73886
74217
|
*/
|
|
73887
|
-
|
|
73888
|
-
|
|
73889
|
-
|
|
73890
|
-
|
|
73891
|
-
|
|
73892
|
-
|
|
73893
|
-
|
|
73894
|
-
|
|
73895
|
-
|
|
73896
|
-
|
|
73897
|
-
|
|
73898
|
-
|
|
73899
|
-
|
|
73900
|
-
|
|
73901
|
-
|
|
73902
|
-
|
|
73903
|
-
|
|
73904
|
-
|
|
73905
|
-
|
|
73906
|
-
|
|
73907
|
-
|
|
73908
|
-
|
|
73909
|
-
|
|
73910
|
-
|
|
74218
|
+
function buildCoderPingPrompt() {
|
|
74219
|
+
return spaceTrim(`
|
|
74220
|
+
# Promptbook connection check
|
|
74221
|
+
|
|
74222
|
+
This is an automated \`ptbk coder ping\` connection check, not a coding task.
|
|
74223
|
+
|
|
74224
|
+
Do exactly this and nothing else:
|
|
74225
|
+
|
|
74226
|
+
1. Multiply \`${CODER_PING_FIRST_FACTOR}\` by \`${CODER_PING_SECOND_FACTOR}\`.
|
|
74227
|
+
2. Answer with one single line \`${CODER_PING_ANSWER_MARKER}: <result>\` where \`<result>\` is the number you computed.
|
|
74228
|
+
|
|
74229
|
+
Rules:
|
|
74230
|
+
|
|
74231
|
+
- Do not read, create, change, move or delete any file.
|
|
74232
|
+
- Do not run any command and do not use any tool.
|
|
74233
|
+
- Do not write anything except the single answer line.
|
|
74234
|
+
`);
|
|
74235
|
+
}
|
|
74236
|
+
|
|
74237
|
+
/**
|
|
74238
|
+
* Pattern matching one answer line produced by the pinged harness.
|
|
74239
|
+
*
|
|
74240
|
+
* The captured answer deliberately stops at a quote, a backslash or a line break, so an answer
|
|
74241
|
+
* embedded in a JSON event stream — as produced by Claude Code, Opencode or Codex `--json` — is
|
|
74242
|
+
* captured without the surrounding JSON.
|
|
74243
|
+
*/
|
|
74244
|
+
const CODER_PING_ANSWER_PATTERN = new RegExp(`${CODER_PING_ANSWER_MARKER}\\s*:[ \\t]*([^\\r\\n"\\\\]*)`, 'gu');
|
|
74245
|
+
/**
|
|
74246
|
+
* Extracts the answer of a pinged harness from the runtime log of its runner shell.
|
|
74247
|
+
*
|
|
74248
|
+
* Only the raw output of the last execution is searched, so the answer marker contained in the
|
|
74249
|
+
* prompt of the raw input is never mistaken for the answer of the harness.
|
|
74250
|
+
*
|
|
74251
|
+
* @returns The answer of the harness, or `null` when the harness produced no recognizable answer
|
|
74252
|
+
*/
|
|
74253
|
+
function extractCoderPingAnswer(runtimeLog) {
|
|
74254
|
+
var _a;
|
|
74255
|
+
const rawOutput = runtimeLog.split(SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER).pop();
|
|
74256
|
+
if (rawOutput === undefined) {
|
|
74257
|
+
return null;
|
|
74258
|
+
}
|
|
74259
|
+
// Note: The last answer wins because harnesses which stream partial messages repeat the growing answer line
|
|
74260
|
+
const answers = Array.from(rawOutput.matchAll(CODER_PING_ANSWER_PATTERN))
|
|
74261
|
+
.map((match) => (match[1] || '').trim())
|
|
74262
|
+
.filter((answer) => answer !== '');
|
|
74263
|
+
return (_a = answers[answers.length - 1]) !== null && _a !== void 0 ? _a : null;
|
|
74264
|
+
}
|
|
74265
|
+
|
|
74266
|
+
/**
|
|
74267
|
+
* Temporary subdirectory used for the `ptbk coder ping` runner shell script and its runtime log.
|
|
74268
|
+
*/
|
|
74269
|
+
const CODER_PING_SCRIPT_DIRECTORY_NAME = 'coder-ping';
|
|
74270
|
+
/**
|
|
74271
|
+
* Base name of the temporary `ptbk coder ping` runner shell script.
|
|
74272
|
+
*/
|
|
74273
|
+
const CODER_PING_SCRIPT_SOURCE_NAME = 'ping';
|
|
74274
|
+
/**
|
|
74275
|
+
* Sends one tiny dummy prompt through the selected harness and model and measures the round trip.
|
|
74276
|
+
*
|
|
74277
|
+
* The ping reuses the very same runner the coding queue uses, so it really exercises the configured
|
|
74278
|
+
* harness, model, thinking level and authentication — including the retry behavior on rate limits.
|
|
74279
|
+
* Both temporary artifacts it creates are removed again, so the project is left as it was.
|
|
74280
|
+
*/
|
|
74281
|
+
async function pingCoderHarness(options) {
|
|
74282
|
+
const projectPath = options.projectPath || process.cwd();
|
|
74283
|
+
const { runner, runnerMetadata } = resolvePromptRunner(options);
|
|
74284
|
+
const scriptPath = buildTemporaryPromptScriptPath({
|
|
74285
|
+
projectPath,
|
|
74286
|
+
scriptDirectoryName: CODER_PING_SCRIPT_DIRECTORY_NAME,
|
|
74287
|
+
sourceFileName: CODER_PING_SCRIPT_SOURCE_NAME,
|
|
74288
|
+
});
|
|
74289
|
+
const startedTimeMs = Date.now();
|
|
74290
|
+
const { answer, usage, loginMethod } = await withPromptRuntimeLog(scriptPath, async (logPath) => {
|
|
74291
|
+
var _a;
|
|
74292
|
+
const result = await runner.runPrompt({
|
|
74293
|
+
prompt: buildCoderPingPrompt(),
|
|
74294
|
+
scriptPath,
|
|
74295
|
+
projectPath,
|
|
74296
|
+
logPath,
|
|
74297
|
+
shouldPrintLiveOutput: (_a = options.shouldPrintLiveOutput) !== null && _a !== void 0 ? _a : false,
|
|
74298
|
+
preserveArtifactsOnSuccess: false,
|
|
73911
74299
|
});
|
|
73912
|
-
return {
|
|
73913
|
-
|
|
73914
|
-
|
|
73915
|
-
|
|
74300
|
+
return { ...result, answer: extractCoderPingAnswer(await readRuntimeLog(logPath)) };
|
|
74301
|
+
}, { preserveArtifactsOnSuccess: false });
|
|
74302
|
+
return {
|
|
74303
|
+
runnerName: runnerMetadata.runnerName,
|
|
74304
|
+
modelName: runnerMetadata.modelName,
|
|
74305
|
+
thinkingLevel: options.thinkingLevel,
|
|
74306
|
+
answer,
|
|
74307
|
+
isAnswerCorrect: answer === CODER_PING_EXPECTED_ANSWER,
|
|
74308
|
+
durationMs: Date.now() - startedTimeMs,
|
|
74309
|
+
usage,
|
|
74310
|
+
loginMethod,
|
|
74311
|
+
};
|
|
74312
|
+
}
|
|
74313
|
+
/**
|
|
74314
|
+
* Reads the runtime log of the finished ping, treating an unreadable log as no output at all.
|
|
74315
|
+
*/
|
|
74316
|
+
async function readRuntimeLog(logPath) {
|
|
74317
|
+
return await promises.readFile(logPath, 'utf-8').catch(() => '');
|
|
74318
|
+
}
|
|
74319
|
+
|
|
74320
|
+
var pingCoderHarness$1 = /*#__PURE__*/Object.freeze({
|
|
74321
|
+
__proto__: null,
|
|
74322
|
+
pingCoderHarness: pingCoderHarness
|
|
74323
|
+
});
|
|
74324
|
+
|
|
74325
|
+
/**
|
|
74326
|
+
* Formats usage price for display in prompt status lines and task details.
|
|
74327
|
+
* Examples:
|
|
74328
|
+
* - "$0.12" (certain)
|
|
74329
|
+
* - "~$3.05" (uncertain)
|
|
74330
|
+
* - "$0.00" (zero cost)
|
|
74331
|
+
* - "<$0.01" (tiny non-zero cost)
|
|
74332
|
+
*
|
|
74333
|
+
* @private internal utility of the prompt runners and the Agents Server task details
|
|
74334
|
+
*/
|
|
74335
|
+
function formatUsagePrice(usage) {
|
|
74336
|
+
const price = usage.price.value;
|
|
74337
|
+
const isUncertain = usage.price.isUncertain === true;
|
|
74338
|
+
const prefix = isUncertain ? '~' : '';
|
|
74339
|
+
if (price === 0) {
|
|
74340
|
+
return `${prefix}$0.00`;
|
|
73916
74341
|
}
|
|
73917
|
-
|
|
73918
|
-
|
|
73919
|
-
|
|
74342
|
+
if (price < 0.01) {
|
|
74343
|
+
return `${prefix}<$0.01`;
|
|
74344
|
+
}
|
|
74345
|
+
if (price < 1) {
|
|
74346
|
+
return `${prefix}$${price.toFixed(4)}`;
|
|
74347
|
+
}
|
|
74348
|
+
return `${prefix}$${price.toFixed(2)}`;
|
|
74349
|
+
}
|
|
74350
|
+
|
|
74351
|
+
/**
|
|
74352
|
+
* Formats runner details for prompt status lines.
|
|
74353
|
+
*/
|
|
74354
|
+
function formatRunnerSignature(runnerName, modelName, thinkingLevel) {
|
|
74355
|
+
const normalizedRunner = runnerName === null || runnerName === void 0 ? void 0 : runnerName.trim();
|
|
74356
|
+
const normalizedModel = modelName === null || modelName === void 0 ? void 0 : modelName.trim();
|
|
74357
|
+
const thinkingLevelSuffix = thinkingLevel ? ` thinking \`${thinkingLevel}\`` : '';
|
|
74358
|
+
if (!normalizedRunner && !normalizedModel) {
|
|
74359
|
+
return 'unknown';
|
|
74360
|
+
}
|
|
74361
|
+
const runnerLabel = normalizedRunner || 'unknown';
|
|
74362
|
+
if (!normalizedModel) {
|
|
74363
|
+
return `${runnerLabel}${thinkingLevelSuffix}`;
|
|
73920
74364
|
}
|
|
74365
|
+
return `${runnerLabel} \`${normalizedModel}\`${thinkingLevelSuffix}`;
|
|
73921
74366
|
}
|
|
73922
74367
|
|
|
73923
|
-
|
|
74368
|
+
/**
|
|
74369
|
+
* Prints the compact summary of one finished `ptbk coder ping`.
|
|
74370
|
+
*/
|
|
74371
|
+
function printCoderPingResult(result) {
|
|
74372
|
+
const runnerSignature = formatRunnerSignature(result.runnerName, result.modelName, result.thinkingLevel);
|
|
74373
|
+
const loginMethodLabel = formatCodexLoginMethod(result.loginMethod);
|
|
74374
|
+
const loginMethodSuffix = loginMethodLabel === undefined ? '' : ` (${loginMethodLabel})`;
|
|
74375
|
+
console.info(colors__default["default"].green(`🏓 ${runnerSignature}${loginMethodSuffix} answered in ${formatCoderPingResponseTime(result.durationMs)}`));
|
|
74376
|
+
console.info(colors__default["default"].gray(` Answer: ${formatCoderPingAnswer(result)}`));
|
|
74377
|
+
console.info(colors__default["default"].gray(` Usage: ${formatCoderPingUsage(result.usage)}`));
|
|
74378
|
+
}
|
|
74379
|
+
/**
|
|
74380
|
+
* Formats the measured round-trip time, keeping the sub-second precision a response time needs.
|
|
74381
|
+
*/
|
|
74382
|
+
function formatCoderPingResponseTime(durationMs) {
|
|
74383
|
+
return `${(durationMs / 1000).toFixed(2)}s`;
|
|
74384
|
+
}
|
|
74385
|
+
/**
|
|
74386
|
+
* Formats the answer of the pinged harness together with what was expected from it.
|
|
74387
|
+
*/
|
|
74388
|
+
function formatCoderPingAnswer(result) {
|
|
74389
|
+
if (result.answer === null) {
|
|
74390
|
+
return `Reached, but the answer line was missing from the output (expected \`${CODER_PING_EXPECTED_ANSWER}\`)`;
|
|
74391
|
+
}
|
|
74392
|
+
if (result.isAnswerCorrect) {
|
|
74393
|
+
return result.answer;
|
|
74394
|
+
}
|
|
74395
|
+
return `${result.answer} (expected \`${CODER_PING_EXPECTED_ANSWER}\`)`;
|
|
74396
|
+
}
|
|
74397
|
+
/**
|
|
74398
|
+
* Formats the resources the pinged harness reported for the dummy work.
|
|
74399
|
+
*/
|
|
74400
|
+
function formatCoderPingUsage(usage) {
|
|
74401
|
+
return [
|
|
74402
|
+
formatUsagePrice(usage),
|
|
74403
|
+
`${formatUncertainCount(usage.input.tokensCount)} input tokens`,
|
|
74404
|
+
`${formatUncertainCount(usage.output.tokensCount)} output tokens`,
|
|
74405
|
+
].join(', ');
|
|
74406
|
+
}
|
|
74407
|
+
/**
|
|
74408
|
+
* Formats one counted usage value, marking an estimated count with a leading `~`.
|
|
74409
|
+
*/
|
|
74410
|
+
function formatUncertainCount(count) {
|
|
74411
|
+
return `${count.isUncertain === true ? '~' : ''}${Math.round(count.value)}`;
|
|
74412
|
+
}
|
|
74413
|
+
|
|
74414
|
+
var printCoderPingResult$1 = /*#__PURE__*/Object.freeze({
|
|
73924
74415
|
__proto__: null,
|
|
73925
|
-
|
|
74416
|
+
printCoderPingResult: printCoderPingResult
|
|
73926
74417
|
});
|
|
73927
74418
|
|
|
73928
74419
|
/**
|
|
@@ -75837,6 +76328,14 @@
|
|
|
75837
76328
|
.filter((statement) => statement !== '');
|
|
75838
76329
|
}
|
|
75839
76330
|
|
|
76331
|
+
/**
|
|
76332
|
+
* Loads the PostgreSQL client (`pg`) on demand
|
|
76333
|
+
*
|
|
76334
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
76335
|
+
*
|
|
76336
|
+
* @private function of runAutoMigrateTestingServers
|
|
76337
|
+
*/
|
|
76338
|
+
const loadPostgresModule = createLazyModuleLoader(() => import('pg'));
|
|
75840
76339
|
/**
|
|
75841
76340
|
* Migration targets for testing servers that should be migrated by coding-script auto-migration.
|
|
75842
76341
|
*/
|
|
@@ -75914,7 +76413,8 @@
|
|
|
75914
76413
|
* @returns Pending migration files grouped by prefix.
|
|
75915
76414
|
*/
|
|
75916
76415
|
async function listPendingMigrationsByPrefix(options) {
|
|
75917
|
-
const
|
|
76416
|
+
const { Client } = await loadPostgresModule();
|
|
76417
|
+
const client = new Client({
|
|
75918
76418
|
connectionString: options.connectionString,
|
|
75919
76419
|
ssl: { rejectUnauthorized: false },
|
|
75920
76420
|
});
|
|
@@ -76071,15 +76571,6 @@
|
|
|
76071
76571
|
return lines.join(file.eol);
|
|
76072
76572
|
}
|
|
76073
76573
|
|
|
76074
|
-
/**
|
|
76075
|
-
* Builds a normalized temporary shell script path for prompt runners.
|
|
76076
|
-
*/
|
|
76077
|
-
function buildTemporaryPromptScriptPath(options) {
|
|
76078
|
-
const sourceFileName = path.basename(options.sourceFileName);
|
|
76079
|
-
const scriptFileName = `${sourceFileName.replace(/\.[^.]+$/u, '')}${options.suffix || ''}.sh`;
|
|
76080
|
-
return resolvePromptbookTemporaryPath(options.projectPath, options.scriptDirectoryName, scriptFileName);
|
|
76081
|
-
}
|
|
76082
|
-
|
|
76083
76574
|
/**
|
|
76084
76575
|
* Builds the suffix which disambiguates one prompt section inside its prompt file.
|
|
76085
76576
|
*
|
|
@@ -76106,32 +76597,6 @@
|
|
|
76106
76597
|
});
|
|
76107
76598
|
}
|
|
76108
76599
|
|
|
76109
|
-
/**
|
|
76110
|
-
* Formats usage price for display in prompt status lines and task details.
|
|
76111
|
-
* Examples:
|
|
76112
|
-
* - "$0.12" (certain)
|
|
76113
|
-
* - "~$3.05" (uncertain)
|
|
76114
|
-
* - "$0.00" (zero cost)
|
|
76115
|
-
* - "<$0.01" (tiny non-zero cost)
|
|
76116
|
-
*
|
|
76117
|
-
* @private internal utility of the prompt runners and the Agents Server task details
|
|
76118
|
-
*/
|
|
76119
|
-
function formatUsagePrice(usage) {
|
|
76120
|
-
const price = usage.price.value;
|
|
76121
|
-
const isUncertain = usage.price.isUncertain === true;
|
|
76122
|
-
const prefix = isUncertain ? '~' : '';
|
|
76123
|
-
if (price === 0) {
|
|
76124
|
-
return `${prefix}$0.00`;
|
|
76125
|
-
}
|
|
76126
|
-
if (price < 0.01) {
|
|
76127
|
-
return `${prefix}<$0.01`;
|
|
76128
|
-
}
|
|
76129
|
-
if (price < 1) {
|
|
76130
|
-
return `${prefix}$${price.toFixed(4)}`;
|
|
76131
|
-
}
|
|
76132
|
-
return `${prefix}$${price.toFixed(2)}`;
|
|
76133
|
-
}
|
|
76134
|
-
|
|
76135
76600
|
/**
|
|
76136
76601
|
* Human-readable labels for each coder run step kind shown in prompt status lines.
|
|
76137
76602
|
*/
|
|
@@ -76176,23 +76641,6 @@
|
|
|
76176
76641
|
return `(failed after ${attemptCount} attempts) `;
|
|
76177
76642
|
}
|
|
76178
76643
|
|
|
76179
|
-
/**
|
|
76180
|
-
* Formats runner details for prompt status lines.
|
|
76181
|
-
*/
|
|
76182
|
-
function formatRunnerSignature(runnerName, modelName, thinkingLevel) {
|
|
76183
|
-
const normalizedRunner = runnerName === null || runnerName === void 0 ? void 0 : runnerName.trim();
|
|
76184
|
-
const normalizedModel = modelName === null || modelName === void 0 ? void 0 : modelName.trim();
|
|
76185
|
-
const thinkingLevelSuffix = thinkingLevel ? ` thinking \`${thinkingLevel}\`` : '';
|
|
76186
|
-
if (!normalizedRunner && !normalizedModel) {
|
|
76187
|
-
return 'unknown';
|
|
76188
|
-
}
|
|
76189
|
-
const runnerLabel = normalizedRunner || 'unknown';
|
|
76190
|
-
if (!normalizedModel) {
|
|
76191
|
-
return `${runnerLabel}${thinkingLevelSuffix}`;
|
|
76192
|
-
}
|
|
76193
|
-
return `${runnerLabel} \`${normalizedModel}\`${thinkingLevelSuffix}`;
|
|
76194
|
-
}
|
|
76195
|
-
|
|
76196
76644
|
/**
|
|
76197
76645
|
* Replaces the complete todo status line while preserving its indentation.
|
|
76198
76646
|
*
|
|
@@ -79346,14 +79794,21 @@
|
|
|
79346
79794
|
let promptFiles = initialFiles;
|
|
79347
79795
|
const skippedFiles = new Set();
|
|
79348
79796
|
while (true) {
|
|
79797
|
+
// Note: The git synchronization is applied around each single verification, not once per whole run
|
|
79798
|
+
await $pullCoderChanges({ gitSync: normalizedOptions.gitSync });
|
|
79799
|
+
if (normalizedOptions.gitSync.isAutoPullEnabled) {
|
|
79800
|
+
// Note: The pull can bring in prompt file changes, so the queue is reloaded before it is used
|
|
79801
|
+
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79802
|
+
}
|
|
79349
79803
|
displayPromptOverview(promptFiles);
|
|
79350
79804
|
// First priority: verify files where all prompts are marked as done
|
|
79351
79805
|
const fileWithAllDone = findFileWithAllDonePrompts(promptFiles, skippedFiles);
|
|
79352
79806
|
if (fileWithAllDone) {
|
|
79353
|
-
const
|
|
79354
|
-
if (wasSkipped) {
|
|
79807
|
+
const outcome = await verifyDonePromptsInFile(fileWithAllDone);
|
|
79808
|
+
if (outcome.wasSkipped) {
|
|
79355
79809
|
skippedFiles.add(fileWithAllDone.path);
|
|
79356
79810
|
}
|
|
79811
|
+
await $commitVerificationOutcome(normalizedOptions.gitSync, outcome);
|
|
79357
79812
|
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79358
79813
|
continue;
|
|
79359
79814
|
}
|
|
@@ -79363,10 +79818,20 @@
|
|
|
79363
79818
|
console.info(colors__default["default"].green('\n✅ All prompts have been verified.'));
|
|
79364
79819
|
break;
|
|
79365
79820
|
}
|
|
79366
|
-
await resolvePrompt(nextPrompt);
|
|
79821
|
+
const outcome = await resolvePrompt(nextPrompt);
|
|
79822
|
+
await $commitVerificationOutcome(normalizedOptions.gitSync, outcome);
|
|
79367
79823
|
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79368
79824
|
}
|
|
79369
79825
|
}
|
|
79826
|
+
/**
|
|
79827
|
+
* Commits and pushes one applied verification when the git synchronization is enabled.
|
|
79828
|
+
*/
|
|
79829
|
+
async function $commitVerificationOutcome(gitSync, outcome) {
|
|
79830
|
+
if (outcome.commitMessage === null) {
|
|
79831
|
+
return;
|
|
79832
|
+
}
|
|
79833
|
+
await $commitCoderChanges({ gitSync, commitMessage: outcome.commitMessage });
|
|
79834
|
+
}
|
|
79370
79835
|
/**
|
|
79371
79836
|
* Parses supported command-line arguments for the standalone verification script.
|
|
79372
79837
|
*/
|
|
@@ -79374,6 +79839,11 @@
|
|
|
79374
79839
|
return {
|
|
79375
79840
|
reverse: args.includes('--reverse'),
|
|
79376
79841
|
ignore: readRepeatableStringOption(args, '--ignore'),
|
|
79842
|
+
gitSync: {
|
|
79843
|
+
isCommitEnabled: args.includes('--commit'),
|
|
79844
|
+
isAutoPushEnabled: args.includes('--auto-push'),
|
|
79845
|
+
isAutoPullEnabled: args.includes('--auto-pull'),
|
|
79846
|
+
},
|
|
79377
79847
|
};
|
|
79378
79848
|
}
|
|
79379
79849
|
/**
|
|
@@ -79425,10 +79895,11 @@
|
|
|
79425
79895
|
* Normalizes verification options so the rest of the flow can assume stable defaults.
|
|
79426
79896
|
*/
|
|
79427
79897
|
function normalizeVerifyPromptsOptions(options) {
|
|
79428
|
-
var _a, _b;
|
|
79898
|
+
var _a, _b, _c;
|
|
79429
79899
|
return {
|
|
79430
79900
|
reverse: (_a = options.reverse) !== null && _a !== void 0 ? _a : false,
|
|
79431
79901
|
ignore: normalizeIgnoreValues((_b = options.ignore) !== null && _b !== void 0 ? _b : []),
|
|
79902
|
+
gitSync: (_c = options.gitSync) !== null && _c !== void 0 ? _c : DISABLED_CODER_GIT_SYNC_OPTIONS,
|
|
79432
79903
|
};
|
|
79433
79904
|
}
|
|
79434
79905
|
/**
|
|
@@ -79559,7 +80030,6 @@
|
|
|
79559
80030
|
/**
|
|
79560
80031
|
* Verifies the last done [x] prompt in a file and decides whether to archive it or add a repair prompt.
|
|
79561
80032
|
* Ignores not-ready prompts like [-], [.], [?], etc.
|
|
79562
|
-
* Returns true if the file was skipped, false otherwise.
|
|
79563
80033
|
*/
|
|
79564
80034
|
async function verifyDonePromptsInFile(file) {
|
|
79565
80035
|
const doneCount = file.sections.filter((s) => s.status === 'done').length;
|
|
@@ -79579,32 +80049,45 @@
|
|
|
79579
80049
|
}
|
|
79580
80050
|
if (!lastDoneSection) {
|
|
79581
80051
|
console.info(colors__default["default"].gray('No done [x] prompts found in this file.'));
|
|
79582
|
-
return false;
|
|
80052
|
+
return { wasSkipped: false, commitMessage: null };
|
|
79583
80053
|
}
|
|
79584
80054
|
console.info(colors__default["default"].gray('Verifying the last [x] prompt in the file...\n'));
|
|
79585
80055
|
displayPromptSnippet({ file, section: lastDoneSection });
|
|
79586
80056
|
const decision = await promptForDoneVerification(file, lastDoneSection);
|
|
79587
80057
|
if (decision === 'done') {
|
|
79588
80058
|
await archivePromptFile(file);
|
|
79589
|
-
return false;
|
|
80059
|
+
return { wasSkipped: false, commitMessage: buildArchiveCommitMessage(file) };
|
|
79590
80060
|
}
|
|
79591
80061
|
else if (decision === 'needs-work') {
|
|
79592
80062
|
console.info(colors__default["default"].yellow('\n⚠️ This prompt needs repair.'));
|
|
79593
80063
|
await appendRepairPrompt(file, lastDoneSection);
|
|
79594
|
-
return false;
|
|
80064
|
+
return { wasSkipped: false, commitMessage: buildRepairCommitMessage(file) };
|
|
79595
80065
|
}
|
|
79596
80066
|
else {
|
|
79597
80067
|
console.info(colors__default["default"].gray('\n⏩ Skipped, no changes made.'));
|
|
79598
|
-
return true;
|
|
80068
|
+
return { wasSkipped: true, commitMessage: null };
|
|
79599
80069
|
}
|
|
79600
80070
|
}
|
|
80071
|
+
/**
|
|
80072
|
+
* Builds the commit message describing one archived prompt file.
|
|
80073
|
+
*/
|
|
80074
|
+
function buildArchiveCommitMessage(file) {
|
|
80075
|
+
return `✅ Prompt done and archived \`${file.name}\``; // <- $commitCoderChanges({
|
|
80076
|
+
}
|
|
80077
|
+
/**
|
|
80078
|
+
* Builds the commit message describing one appended repair prompt.
|
|
80079
|
+
*/
|
|
80080
|
+
function buildRepairCommitMessage(file) {
|
|
80081
|
+
return `❌ Repair prompt added into \`${file.name}\``; // <- $commitCoderChanges({
|
|
80082
|
+
}
|
|
79601
80083
|
/**
|
|
79602
80084
|
* Asks the user to verify if a done prompt is actually completed.
|
|
79603
80085
|
* Returns 'done' if verified, 'needs-work' if not done, or 'skip' to skip this file.
|
|
79604
80086
|
*/
|
|
79605
80087
|
async function promptForDoneVerification(file, section) {
|
|
79606
80088
|
const promptLabel = buildPromptLabelForDisplay(file, section);
|
|
79607
|
-
const
|
|
80089
|
+
const { default: prompts } = await loadPromptsModule();
|
|
80090
|
+
const response = await prompts({
|
|
79608
80091
|
type: 'select',
|
|
79609
80092
|
name: 'verified',
|
|
79610
80093
|
message: `Is ${colors__default["default"].bold(promptLabel)} actually done?`,
|
|
@@ -79672,17 +80155,18 @@
|
|
|
79672
80155
|
const decision = await promptForDecision(selection);
|
|
79673
80156
|
if (decision === 'done') {
|
|
79674
80157
|
await archivePromptFile(selection.file);
|
|
80158
|
+
return { wasSkipped: false, commitMessage: buildArchiveCommitMessage(selection.file) };
|
|
79675
80159
|
}
|
|
79676
|
-
|
|
79677
|
-
|
|
79678
|
-
}
|
|
80160
|
+
await appendRepairPrompt(selection.file, selection.section);
|
|
80161
|
+
return { wasSkipped: false, commitMessage: buildRepairCommitMessage(selection.file) };
|
|
79679
80162
|
}
|
|
79680
80163
|
/**
|
|
79681
80164
|
* Presents the interactive decision menu for the current prompt section.
|
|
79682
80165
|
*/
|
|
79683
80166
|
async function promptForDecision(selection) {
|
|
79684
80167
|
const promptLabel = buildPromptLabelForDisplay(selection.file, selection.section);
|
|
79685
|
-
const
|
|
80168
|
+
const { default: prompts } = await loadPromptsModule();
|
|
80169
|
+
const response = await prompts({
|
|
79686
80170
|
type: 'select',
|
|
79687
80171
|
name: 'decision',
|
|
79688
80172
|
message: `Is ${colors__default["default"].bold(promptLabel)} resolved?`,
|