@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/esm/index.es.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import colors from 'colors';
|
|
2
2
|
import commander, { Option } from 'commander';
|
|
3
3
|
import _spaceTrim, { spaceTrim as spaceTrim$1 } from 'spacetrim';
|
|
4
|
-
import { writeFile, stat, mkdir, readFile, readdir, rm, cp, lstat, symlink, rename, unlink, appendFile, realpath, copyFile, access, constants, watch, rmdir
|
|
4
|
+
import { writeFile, stat, mkdir, readFile, readdir, rm, cp, lstat, symlink, rename, unlink, appendFile, realpath, copyFile, access, constants, watch, rmdir } from 'fs/promises';
|
|
5
5
|
import { join, delimiter, relative, basename, resolve, dirname, isAbsolute, extname } from 'path';
|
|
6
6
|
import { createHash, randomBytes } from 'crypto';
|
|
7
7
|
import { spawn } from 'child_process';
|
|
@@ -12,13 +12,8 @@ import * as dotenv from 'dotenv';
|
|
|
12
12
|
import * as readline from 'readline';
|
|
13
13
|
import { emitKeypressEvents, clearLine, cursorTo, createInterface } from 'readline';
|
|
14
14
|
import { forTime, forEver } from 'waitasecond';
|
|
15
|
-
import prompts from 'prompts';
|
|
16
15
|
import hexEncoder from 'crypto-js/enc-hex';
|
|
17
16
|
import sha256 from 'crypto-js/sha256';
|
|
18
|
-
import { io } from 'socket.io-client';
|
|
19
|
-
import JSZip from 'jszip';
|
|
20
|
-
import { Readability } from '@mozilla/readability';
|
|
21
|
-
import { JSDOM } from 'jsdom';
|
|
22
17
|
import CryptoJS from 'crypto-js';
|
|
23
18
|
import showdown from 'showdown';
|
|
24
19
|
import glob from 'glob-promise';
|
|
@@ -29,19 +24,13 @@ import * as OpenApiValidator from 'express-openapi-validator';
|
|
|
29
24
|
import swaggerUi from 'swagger-ui-express';
|
|
30
25
|
import { createElement } from 'react';
|
|
31
26
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
32
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
33
27
|
import Bottleneck from 'bottleneck';
|
|
34
|
-
import { OpenAIClient, AzureKeyCredential } from '@azure/openai';
|
|
35
28
|
import { Subject, BehaviorSubject } from 'rxjs';
|
|
36
|
-
import { fileSearchTool, tool, Agent as Agent$1, webSearchTool, run, setDefaultOpenAIClient, setDefaultOpenAIKey } from '@openai/agents';
|
|
37
|
-
import OpenAI from 'openai';
|
|
38
|
-
import * as ts from 'typescript';
|
|
39
29
|
import ignore from 'ignore';
|
|
40
|
-
import { tmpdir } from 'os';
|
|
41
30
|
import { EventEmitter } from 'events';
|
|
31
|
+
import { tmpdir } from 'os';
|
|
42
32
|
import { lookup, extension } from 'mime-types';
|
|
43
33
|
import papaparse from 'papaparse';
|
|
44
|
-
import { Client } from 'pg';
|
|
45
34
|
import '@supabase/supabase-js';
|
|
46
35
|
import { pathToFileURL } from 'url';
|
|
47
36
|
|
|
@@ -59,7 +48,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
59
48
|
* @generated
|
|
60
49
|
* @see https://github.com/webgptorg/promptbook
|
|
61
50
|
*/
|
|
62
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-
|
|
51
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.114.0-3';
|
|
63
52
|
/**
|
|
64
53
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
65
54
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -3293,6 +3282,12 @@ const PTBK_AGENTS_SERVER_BUILD_WORKER_COUNT_ENV = 'PTBK_AGENTS_SERVER_BUILD_WORK
|
|
|
3293
3282
|
* @private internal constant of `buildAgentsServer`
|
|
3294
3283
|
*/
|
|
3295
3284
|
const PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION_ENV = 'PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION';
|
|
3285
|
+
/**
|
|
3286
|
+
* Environment variable that disables throwaway webpack filesystem caches for CLI-owned production builds.
|
|
3287
|
+
*
|
|
3288
|
+
* @private internal constant of `buildAgentsServer`
|
|
3289
|
+
*/
|
|
3290
|
+
const PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE_ENV = 'PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE';
|
|
3296
3291
|
/**
|
|
3297
3292
|
* Conservative Next.js build worker count used by CLI-owned Agents Server production builds.
|
|
3298
3293
|
*
|
|
@@ -3317,6 +3312,11 @@ function createAgentsServerRuntimeEnvironment(environment, nodeModulesPath, opti
|
|
|
3317
3312
|
[PTBK_AGENTS_SERVER_IGNORE_NEXT_VALIDATION_ENV]: 'true',
|
|
3318
3313
|
}
|
|
3319
3314
|
: {}),
|
|
3315
|
+
...(options.isWebpackFilesystemCacheDisabled
|
|
3316
|
+
? {
|
|
3317
|
+
[PTBK_AGENTS_SERVER_DISABLE_WEBPACK_FILESYSTEM_CACHE_ENV]: 'true',
|
|
3318
|
+
}
|
|
3319
|
+
: {}),
|
|
3320
3320
|
};
|
|
3321
3321
|
}
|
|
3322
3322
|
/**
|
|
@@ -4050,6 +4050,7 @@ async function ensureAgentsServerBuild(options = {}) {
|
|
|
4050
4050
|
});
|
|
4051
4051
|
const buildEnvironment = createAgentsServerRuntimeEnvironment(environment, preparedRuntime.nodeModulesPath, {
|
|
4052
4052
|
isNextValidationIgnored: preparedRuntime.isAppPathMaterialized,
|
|
4053
|
+
isWebpackFilesystemCacheDisabled: true,
|
|
4053
4054
|
});
|
|
4054
4055
|
if (!options.isBuildForced &&
|
|
4055
4056
|
(await isAgentsServerBuildCacheCurrent({
|
|
@@ -28226,6 +28227,13 @@ function toPosixPath(filePath) {
|
|
|
28226
28227
|
* Environment variable read by the shell wrapper to tee live output into the temporary runtime log file.
|
|
28227
28228
|
*/
|
|
28228
28229
|
const PTBK_CODER_LOG_FILE_ENV_NAME = 'PTBK_CODER_LOG_FILE';
|
|
28230
|
+
/**
|
|
28231
|
+
* Log line which separates the raw script input from the raw script output of one execution section.
|
|
28232
|
+
*
|
|
28233
|
+
* Readers of a runtime log split on this marker to look only at what the harness really produced,
|
|
28234
|
+
* without the generated script and the prompt it embeds.
|
|
28235
|
+
*/
|
|
28236
|
+
const SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER = '--- raw output ---';
|
|
28229
28237
|
/**
|
|
28230
28238
|
* Small bash wrapper that preserves stdout/stderr streams while teeing both into the runtime log file.
|
|
28231
28239
|
*/
|
|
@@ -28261,7 +28269,7 @@ async function appendScriptExecutionLogStart({ scriptPath, scriptContent, logPat
|
|
|
28261
28269
|
--- raw input ---
|
|
28262
28270
|
${block(normalizedInput)}
|
|
28263
28271
|
|
|
28264
|
-
|
|
28272
|
+
${SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER}
|
|
28265
28273
|
`);
|
|
28266
28274
|
await appendFile(logPath, `${logSection}\n`, 'utf-8');
|
|
28267
28275
|
}
|
|
@@ -32938,8 +32946,12 @@ function readOptionalSigningKeyValue() {
|
|
|
32938
32946
|
* `options.includePaths` can restrict staging, `options.onlyPaths` can restrict the commit pathspec,
|
|
32939
32947
|
* `options.excludePaths` can keep temporary artifacts out of the created commit and
|
|
32940
32948
|
* `options.isEmptyCommitAllowed` keeps a round without any file change from failing.
|
|
32949
|
+
*
|
|
32950
|
+
* Note: The temporary commit message file is written inside the project, so it is always excluded from the commit
|
|
32951
|
+
* itself for projects which do not keep the Promptbook temporary directory out of version control.
|
|
32941
32952
|
*/
|
|
32942
32953
|
async function commitChanges(message, options) {
|
|
32954
|
+
var _a;
|
|
32943
32955
|
const projectPath = (options === null || options === void 0 ? void 0 : options.projectPath) || process.cwd();
|
|
32944
32956
|
const commitMessagePath = resolvePromptbookTemporaryPath(projectPath, 'ptbk-coder', 'commit-messages', `COMMIT_MESSAGE_${Date.now()}.txt`);
|
|
32945
32957
|
await mkdir(dirname(commitMessagePath), { recursive: true });
|
|
@@ -32947,7 +32959,10 @@ async function commitChanges(message, options) {
|
|
|
32947
32959
|
try {
|
|
32948
32960
|
const agentEnv = buildAgentGitEnv();
|
|
32949
32961
|
const signingFlag = buildAgentGitSigningFlag();
|
|
32950
|
-
await stageCommitChanges(projectPath, agentEnv, options === null || options === void 0 ? void 0 : options.includePaths,
|
|
32962
|
+
await stageCommitChanges(projectPath, agentEnv, options === null || options === void 0 ? void 0 : options.includePaths, [
|
|
32963
|
+
commitMessagePath,
|
|
32964
|
+
...((_a = options === null || options === void 0 ? void 0 : options.excludePaths) !== null && _a !== void 0 ? _a : []),
|
|
32965
|
+
]);
|
|
32951
32966
|
await runGitCommand({
|
|
32952
32967
|
command: buildGitCommitCommand({
|
|
32953
32968
|
commitMessagePath,
|
|
@@ -42287,6 +42302,91 @@ function $initializeAgentsServerCommand(program) {
|
|
|
42287
42302
|
// Note: [🟡] Code for CLI command [agents-server](src/cli/cli-commands/agents-server.ts) should never be published outside of `@promptbook/cli`
|
|
42288
42303
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
42289
42304
|
|
|
42305
|
+
/**
|
|
42306
|
+
* Creates a loader which imports one module on the first call and reuses the very same module afterwards
|
|
42307
|
+
*
|
|
42308
|
+
* Note: [🐌] Heavy third-party dependencies are imported lazily to keep the startup of the Promptbook CLI fast.
|
|
42309
|
+
* A statically imported dependency is loaded every single time the bundle is loaded, even when the running
|
|
42310
|
+
* command never touches it. A lazily imported dependency is loaded only when the feature is really used.
|
|
42311
|
+
*
|
|
42312
|
+
* @example
|
|
42313
|
+
* const loadJsdomModule = createLazyModuleLoader(() => import('jsdom'));
|
|
42314
|
+
* const { JSDOM } = await loadJsdomModule();
|
|
42315
|
+
*
|
|
42316
|
+
* @private internal utility of Promptbook
|
|
42317
|
+
*/
|
|
42318
|
+
function createLazyModuleLoader(importModule) {
|
|
42319
|
+
let importedModulePromise = null;
|
|
42320
|
+
return function loadModule() {
|
|
42321
|
+
if (importedModulePromise === null) {
|
|
42322
|
+
importedModulePromise = importModule();
|
|
42323
|
+
}
|
|
42324
|
+
return importedModulePromise;
|
|
42325
|
+
};
|
|
42326
|
+
}
|
|
42327
|
+
// Note: [🐌] Do not convert the lazy `import(...)` calls back to static `import` statements, it would bring back the
|
|
42328
|
+
// slow startup of the `ptbk` CLI utility
|
|
42329
|
+
|
|
42330
|
+
/**
|
|
42331
|
+
* Loads the interactive terminal prompt library (`prompts`) on demand
|
|
42332
|
+
*
|
|
42333
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast - most commands never ask the user
|
|
42334
|
+
* anything interactively
|
|
42335
|
+
*
|
|
42336
|
+
* @private internal utility of Promptbook CLI
|
|
42337
|
+
*/
|
|
42338
|
+
const loadPromptsModule = createLazyModuleLoader(() => import('prompts'));
|
|
42339
|
+
// Note: [🟡] Code for CLI prompt loading [loadPromptsModule](src/cli/common/loadPromptsModule.ts) should never be published outside of `@promptbook/cli`
|
|
42340
|
+
|
|
42341
|
+
/**
|
|
42342
|
+
* Description block shared by the `ptbk coder` commands which can synchronize their changes with git.
|
|
42343
|
+
*
|
|
42344
|
+
* @private internal utility of `promptbookCli`
|
|
42345
|
+
*/
|
|
42346
|
+
const CODER_GIT_SYNC_DESCRIPTION = spaceTrim$1(`
|
|
42347
|
+
Git synchronization:
|
|
42348
|
+
- --auto-pull pulls the latest changes before this command changes anything
|
|
42349
|
+
- --commit commits the changes made by this command
|
|
42350
|
+
- --auto-push pushes the created commit to the remote repository
|
|
42351
|
+
`);
|
|
42352
|
+
/**
|
|
42353
|
+
* Registers the shared `--commit`, `--auto-push` and `--auto-pull` flags on a `ptbk coder` command.
|
|
42354
|
+
*
|
|
42355
|
+
* Note: Unlike `ptbk coder run`, which commits by default and opts out through `--no-commit`,
|
|
42356
|
+
* these commands never touch git unless the flags are used explicitly.
|
|
42357
|
+
*
|
|
42358
|
+
* @private internal utility of `promptbookCli`
|
|
42359
|
+
*/
|
|
42360
|
+
function addCoderGitSyncOptions(command) {
|
|
42361
|
+
command.option('--commit', 'Commit the changes made by this command with the coding-agent git identity', false);
|
|
42362
|
+
command.option('--auto-push', 'Automatically git push the created commit, requires --commit', false);
|
|
42363
|
+
command.option('--auto-pull', 'Automatically git pull the latest changes before this command changes anything', false);
|
|
42364
|
+
}
|
|
42365
|
+
/**
|
|
42366
|
+
* Converts the Commander git synchronization flags into normalized git synchronization options.
|
|
42367
|
+
*
|
|
42368
|
+
* @private internal utility of `promptbookCli`
|
|
42369
|
+
*/
|
|
42370
|
+
function normalizeCoderGitSyncCliOptions(cliOptions) {
|
|
42371
|
+
if (cliOptions.autoPush && !cliOptions.commit) {
|
|
42372
|
+
throw new NotAllowed(spaceTrim$1(`
|
|
42373
|
+
Flag \`--auto-push\` can be used only together with \`--commit\`.
|
|
42374
|
+
|
|
42375
|
+
**There is nothing to push when the changes are not committed.**
|
|
42376
|
+
|
|
42377
|
+
Actionable hint:
|
|
42378
|
+
- Add \`--commit\`, for example \`ptbk coder init --commit --auto-push\`.
|
|
42379
|
+
`));
|
|
42380
|
+
}
|
|
42381
|
+
return {
|
|
42382
|
+
isCommitEnabled: cliOptions.commit,
|
|
42383
|
+
isAutoPushEnabled: cliOptions.autoPush,
|
|
42384
|
+
isAutoPullEnabled: cliOptions.autoPull,
|
|
42385
|
+
};
|
|
42386
|
+
}
|
|
42387
|
+
// Note: [🟡] Code for CLI git synchronization options [coderGitSyncCliOptions](src/cli/cli-commands/common/coderGitSyncCliOptions.ts) should never be published outside of `@promptbook/cli`
|
|
42388
|
+
// Note: [💞] Ignore a discrepancy between file name and exported helper names
|
|
42389
|
+
|
|
42290
42390
|
/**
|
|
42291
42391
|
* Relative path to the root prompts directory used by Promptbook coder utilities.
|
|
42292
42392
|
*
|
|
@@ -42540,15 +42640,17 @@ const FALLBACK_PROMPT_SLUG = 'prompt';
|
|
|
42540
42640
|
*/
|
|
42541
42641
|
function $initializeCoderAddCommand(program) {
|
|
42542
42642
|
const command = program.command('add');
|
|
42543
|
-
command.description(spaceTrim$1(`
|
|
42544
|
-
|
|
42643
|
+
command.description(spaceTrim$1((block) => `
|
|
42644
|
+
Add one ready-to-run prompt file to the queue
|
|
42545
42645
|
|
|
42546
|
-
|
|
42547
|
-
|
|
42548
|
-
|
|
42549
|
-
|
|
42550
|
-
|
|
42551
|
-
|
|
42646
|
+
Provide the description as an argument, pipe it through stdin, or run without arguments to type it interactively:
|
|
42647
|
+
- \`ptbk coder add "some new feature"\`
|
|
42648
|
+
- \`ptbk coder add --priority 1 "some new feature"\`
|
|
42649
|
+
- \`ptbk coder add <<EOF ... EOF\`
|
|
42650
|
+
- \`ptbk coder add\`
|
|
42651
|
+
|
|
42652
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
42653
|
+
`));
|
|
42552
42654
|
command.argument('[description]', 'Plain-language description of the feature or task to implement');
|
|
42553
42655
|
command.option('--priority <priority>', 'Priority of the new prompt — higher priorities run first (rendered as trailing `!` markers)', parsePriorityOption, 0);
|
|
42554
42656
|
command.option('--template <template>', spaceTrim$1(`
|
|
@@ -42558,15 +42660,26 @@ function $initializeCoderAddCommand(program) {
|
|
|
42558
42660
|
.map(({ id }) => id)
|
|
42559
42661
|
.join(', ')}) or a markdown file path relative to the current project root.
|
|
42560
42662
|
`));
|
|
42663
|
+
addCoderGitSyncOptions(command);
|
|
42561
42664
|
command.action(handleActionErrors(async (descriptionArgument, cliOptions) => {
|
|
42562
42665
|
const { priority, template: templateOption } = cliOptions;
|
|
42666
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
42667
|
+
const projectPath = process.cwd();
|
|
42563
42668
|
const description = await resolveCoderPromptDescription(descriptionArgument);
|
|
42564
|
-
|
|
42565
|
-
|
|
42669
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
42670
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
42671
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
42672
|
+
const { /* filePath,*/ emojiTag } = await addCoderPrompt({
|
|
42673
|
+
projectPath,
|
|
42566
42674
|
description,
|
|
42567
42675
|
priority,
|
|
42568
42676
|
templateOption,
|
|
42569
42677
|
});
|
|
42678
|
+
await $commitCoderChanges({
|
|
42679
|
+
gitSync,
|
|
42680
|
+
projectPath,
|
|
42681
|
+
commitMessage: `${emojiTag} Add prompt`,
|
|
42682
|
+
});
|
|
42570
42683
|
}));
|
|
42571
42684
|
}
|
|
42572
42685
|
/**
|
|
@@ -42640,6 +42753,7 @@ async function resolveCoderPromptDescription(descriptionArgument) {
|
|
|
42640
42753
|
}
|
|
42641
42754
|
return standardInputDescription;
|
|
42642
42755
|
}
|
|
42756
|
+
const { default: prompts } = await loadPromptsModule();
|
|
42643
42757
|
const response = await prompts({
|
|
42644
42758
|
type: 'text',
|
|
42645
42759
|
name: 'description',
|
|
@@ -43060,9 +43174,11 @@ function parseIntOption(value) {
|
|
|
43060
43174
|
*/
|
|
43061
43175
|
function $initializeCoderGenerateBoilerplatesCommand(program) {
|
|
43062
43176
|
const command = program.command('generate-boilerplates');
|
|
43063
|
-
command.description(spaceTrim$1(`
|
|
43064
|
-
|
|
43065
|
-
|
|
43177
|
+
command.description(spaceTrim$1((block) => `
|
|
43178
|
+
Generate prompt boilerplate files with unique emoji tags
|
|
43179
|
+
|
|
43180
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
43181
|
+
`));
|
|
43066
43182
|
command.option('--count <count>', `Number of prompt boilerplate files to generate`, '5');
|
|
43067
43183
|
command.option('--template <template>', spaceTrim$1(`
|
|
43068
43184
|
Prompt template to use.
|
|
@@ -43071,14 +43187,25 @@ function $initializeCoderGenerateBoilerplatesCommand(program) {
|
|
|
43071
43187
|
.map(({ id }) => id)
|
|
43072
43188
|
.join(', ')}) or a markdown file path relative to the current project root.
|
|
43073
43189
|
`));
|
|
43190
|
+
addCoderGitSyncOptions(command);
|
|
43074
43191
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
43075
43192
|
const { count: countOption, template: templateOption } = cliOptions;
|
|
43076
43193
|
const filesCount = parseFilesCount(countOption);
|
|
43194
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
43195
|
+
const projectPath = process.cwd();
|
|
43196
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
43197
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
43198
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
43077
43199
|
await generatePromptBoilerplate({
|
|
43078
|
-
projectPath
|
|
43200
|
+
projectPath,
|
|
43079
43201
|
filesCount,
|
|
43080
43202
|
templateOption,
|
|
43081
43203
|
});
|
|
43204
|
+
await $commitCoderChanges({
|
|
43205
|
+
gitSync,
|
|
43206
|
+
projectPath,
|
|
43207
|
+
commitMessage: `Prompts ${filesCount}x`,
|
|
43208
|
+
});
|
|
43082
43209
|
return process.exit(0);
|
|
43083
43210
|
}));
|
|
43084
43211
|
}
|
|
@@ -44054,12 +44181,24 @@ function $initializeCoderInitCommand(program) {
|
|
|
44054
44181
|
|
|
44055
44182
|
Checks that the coding harnesses are installed globally and up to date:
|
|
44056
44183
|
${block(listCheckedHarnessLabels())}
|
|
44184
|
+
|
|
44185
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
44057
44186
|
`));
|
|
44058
|
-
command
|
|
44187
|
+
addCoderGitSyncOptions(command);
|
|
44188
|
+
command.action(handleActionErrors(async (cliOptions) => {
|
|
44189
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
44059
44190
|
const projectPath = process.cwd();
|
|
44191
|
+
// Note: Import the git synchronization dynamically to keep the CLI fast for runs without `--commit`
|
|
44192
|
+
const { $commitCoderChanges, $pullCoderChanges } = await Promise.resolve().then(function () { return coderGitSync; });
|
|
44193
|
+
await $pullCoderChanges({ gitSync, projectPath });
|
|
44060
44194
|
const summary = await initializeCoderProjectConfiguration(projectPath);
|
|
44061
44195
|
printInitializationSummary(summary);
|
|
44062
44196
|
await generatePromptBoilerplate({ projectPath, filesCount: 5 });
|
|
44197
|
+
await $commitCoderChanges({
|
|
44198
|
+
gitSync,
|
|
44199
|
+
projectPath,
|
|
44200
|
+
commitMessage: 'Initialize Promptbook Coder',
|
|
44201
|
+
});
|
|
44063
44202
|
await $ensureHarnessInstallations(CODER_INIT_CHECKED_HARNESS_NAMES);
|
|
44064
44203
|
}));
|
|
44065
44204
|
}
|
|
@@ -44081,62 +44220,44 @@ function listDefaultCoderProjectPromptTemplateDisplayPaths() {
|
|
|
44081
44220
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44082
44221
|
|
|
44083
44222
|
/**
|
|
44084
|
-
* Initializes `coder ping` command for Promptbook CLI utilities
|
|
44223
|
+
* Initializes `coder ping` command for Promptbook CLI utilities
|
|
44085
44224
|
*
|
|
44086
|
-
*
|
|
44087
|
-
* and reports how long the harness/model turn took.
|
|
44088
|
-
*
|
|
44089
|
-
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI.
|
|
44225
|
+
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI
|
|
44090
44226
|
*
|
|
44091
44227
|
* @private internal function of `promptbookCli`
|
|
44092
44228
|
*/
|
|
44093
44229
|
function $initializeCoderPingCommand(program) {
|
|
44094
44230
|
const command = program.command('ping');
|
|
44095
44231
|
command.description(spaceTrim$1(`
|
|
44096
|
-
|
|
44232
|
+
Send one tiny dummy prompt to a harness and model to measure and warm them up
|
|
44097
44233
|
|
|
44098
44234
|
${PROMPT_RUNNER_DESCRIPTION}
|
|
44099
44235
|
|
|
44100
44236
|
Features:
|
|
44101
|
-
-
|
|
44102
|
-
-
|
|
44103
|
-
-
|
|
44104
|
-
-
|
|
44237
|
+
- Verifies that the selected harness, model, thinking level and authentication really work
|
|
44238
|
+
- Reports the answer of the harness, the response time and the reported usage
|
|
44239
|
+
- Starts the hourly/weekly quota window before you need it, so it is already refreshing when you do
|
|
44240
|
+
- Leaves the project exactly as it was — nothing is read, written, changed or committed
|
|
44241
|
+
- Use --no-ui to stream the raw harness output instead of only the compact result
|
|
44105
44242
|
`));
|
|
44106
44243
|
addPromptRunnerSelectionOptions(command);
|
|
44107
44244
|
addPromptRunnerRuntimeOptions(command);
|
|
44108
44245
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
44109
|
-
const
|
|
44110
|
-
|
|
44111
|
-
|
|
44112
|
-
|
|
44113
|
-
|
|
44114
|
-
|
|
44115
|
-
|
|
44116
|
-
|
|
44117
|
-
|
|
44118
|
-
|
|
44119
|
-
|
|
44120
|
-
const { runCoderPing } = await Promise.resolve().then(function () { return runCoderPing$1; });
|
|
44121
|
-
const pingResult = await runCoderPing({
|
|
44122
|
-
agentName,
|
|
44123
|
-
model: normalizedOptions.model,
|
|
44124
|
-
thinkingLevel: normalizedOptions.thinkingLevel,
|
|
44125
|
-
isUiDisabled: normalizedOptions.noUi,
|
|
44126
|
-
isCreditsAllowed: normalizedOptions.allowCredits,
|
|
44246
|
+
const runnerOptions = normalizePromptRunnerSelectionCliOptions(cliOptions, { isAgentRequired: true });
|
|
44247
|
+
await $ensureHarnessInstallations([runnerOptions.agentName]);
|
|
44248
|
+
// Note: Import the ping dynamically to avoid loading heavy dependencies until needed
|
|
44249
|
+
const { pingCoderHarness } = await Promise.resolve().then(function () { return pingCoderHarness$1; });
|
|
44250
|
+
const { printCoderPingResult } = await Promise.resolve().then(function () { return printCoderPingResult$1; });
|
|
44251
|
+
const result = await pingCoderHarness({
|
|
44252
|
+
agentName: runnerOptions.agentName,
|
|
44253
|
+
model: runnerOptions.model,
|
|
44254
|
+
thinkingLevel: runnerOptions.thinkingLevel,
|
|
44255
|
+
allowCredits: runnerOptions.allowCredits,
|
|
44256
|
+
shouldPrintLiveOutput: runnerOptions.noUi,
|
|
44127
44257
|
});
|
|
44128
|
-
printCoderPingResult(
|
|
44258
|
+
printCoderPingResult(result);
|
|
44129
44259
|
}));
|
|
44130
44260
|
}
|
|
44131
|
-
/**
|
|
44132
|
-
* Prints the result and duration of one completed coder ping.
|
|
44133
|
-
*/
|
|
44134
|
-
function printCoderPingResult(pingResult) {
|
|
44135
|
-
console.info(spaceTrim$1(`
|
|
44136
|
-
Result: ${pingResult.result}
|
|
44137
|
-
Time: ${pingResult.elapsedTimeMs.toFixed(0)} ms
|
|
44138
|
-
`));
|
|
44139
|
-
}
|
|
44140
44261
|
// Note: [🟡] Code for CLI command [ping](src/cli/cli-commands/coder/ping.ts) should never be published outside of `@promptbook/cli`
|
|
44141
44262
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
44142
44263
|
|
|
@@ -44507,25 +44628,31 @@ function normalizeCommandOptionValue(value) {
|
|
|
44507
44628
|
*/
|
|
44508
44629
|
function $initializeCoderVerifyCommand(program) {
|
|
44509
44630
|
const command = program.command('verify');
|
|
44510
|
-
command.description(spaceTrim$1(`
|
|
44511
|
-
|
|
44631
|
+
command.description(spaceTrim$1((block) => `
|
|
44632
|
+
Interactive verification helper for completed prompts
|
|
44512
44633
|
|
|
44513
|
-
|
|
44514
|
-
|
|
44515
|
-
|
|
44516
|
-
|
|
44517
|
-
|
|
44518
|
-
|
|
44519
|
-
|
|
44520
|
-
|
|
44634
|
+
Features:
|
|
44635
|
+
- Displays list of prompt files with status counts
|
|
44636
|
+
- Guides through verification of completed prompts marked [x]
|
|
44637
|
+
- Archives verified prompt files to prompts/done/ directory
|
|
44638
|
+
- Auto-appends repair prompts for incomplete work
|
|
44639
|
+
- Processes files with all-done prompts first
|
|
44640
|
+
- Supports ignoring matching prompt candidates for one verification run
|
|
44641
|
+
|
|
44642
|
+
${block(CODER_GIT_SYNC_DESCRIPTION)}
|
|
44643
|
+
|
|
44644
|
+
Note: The git synchronization is applied around each single verification, not once per run.
|
|
44645
|
+
`));
|
|
44521
44646
|
command.option('--reverse', 'Process prompt files in reverse order', false);
|
|
44522
44647
|
command.option('--ignore <candidate-text>', 'Ignore prompt files whose filename or first prompt line contains the given text (repeatable)', collectStringOption, []);
|
|
44648
|
+
addCoderGitSyncOptions(command);
|
|
44523
44649
|
command.action(handleActionErrors(async (cliOptions) => {
|
|
44524
44650
|
const { reverse, ignore } = cliOptions;
|
|
44651
|
+
const gitSync = normalizeCoderGitSyncCliOptions(cliOptions);
|
|
44525
44652
|
// Note: Import the main function dynamically to avoid loading heavy dependencies until needed
|
|
44526
44653
|
const { verifyPrompts } = await Promise.resolve().then(function () { return verifyPrompts$1; });
|
|
44527
44654
|
try {
|
|
44528
|
-
await verifyPrompts({ reverse, ignore });
|
|
44655
|
+
await verifyPrompts({ reverse, ignore, gitSync });
|
|
44529
44656
|
}
|
|
44530
44657
|
catch (error) {
|
|
44531
44658
|
console.error(colors.bgRed('Prompt verification failed:'), error);
|
|
@@ -44553,8 +44680,8 @@ function collectStringOption(value, previousValues) {
|
|
|
44553
44680
|
* - add: Add one ready-to-run prompt file to the queue
|
|
44554
44681
|
* - generate-boilerplates: Generate prompt boilerplate files
|
|
44555
44682
|
* - find-refactor-candidates: Find files that need refactoring
|
|
44556
|
-
* - ping: Test one harness and model connection with a disposable task
|
|
44557
44683
|
* - run: Run coding prompts with AI agents
|
|
44684
|
+
* - ping: Test one harness and model with a tiny dummy prompt
|
|
44558
44685
|
* - verify: Verify completed prompts
|
|
44559
44686
|
* - find-fresh-emoji-tags: Find unused emoji tags
|
|
44560
44687
|
*
|
|
@@ -44573,8 +44700,8 @@ function $initializeCoderCommand(program) {
|
|
|
44573
44700
|
- generate-boilerplates: Generate prompt boilerplate files
|
|
44574
44701
|
- find-refactor-candidates: Find files that need refactoring
|
|
44575
44702
|
- find-unwritten: List prompt sections that still need to be authored
|
|
44576
|
-
- ping: Test one harness and model connection with a disposable task
|
|
44577
44703
|
- run: Run coding prompts with AI agents
|
|
44704
|
+
- ping: Test the connection, response time and quota of one harness and model
|
|
44578
44705
|
- server: Start a long-running coder server with a kanban web UI
|
|
44579
44706
|
- verify: Verify completed prompts
|
|
44580
44707
|
- find-fresh-emoji-tags: Find unused emoji tags
|
|
@@ -44585,8 +44712,8 @@ function $initializeCoderCommand(program) {
|
|
|
44585
44712
|
$initializeCoderGenerateBoilerplatesCommand(coderCommand);
|
|
44586
44713
|
$initializeCoderFindRefactorCandidatesCommand(coderCommand);
|
|
44587
44714
|
$initializeCoderFindUnwrittenCommand(coderCommand);
|
|
44588
|
-
$initializeCoderPingCommand(coderCommand);
|
|
44589
44715
|
$initializeCoderRunCommand(coderCommand);
|
|
44716
|
+
$initializeCoderPingCommand(coderCommand);
|
|
44590
44717
|
$initializeCoderServerCommand(coderCommand);
|
|
44591
44718
|
$initializeCoderVerifyCommand(coderCommand);
|
|
44592
44719
|
$initializeCoderFindFreshEmojiTagCommand(coderCommand);
|
|
@@ -45420,6 +45547,14 @@ class FileCacheStorage {
|
|
|
45420
45547
|
// 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
|
|
45421
45548
|
// TODO: [🌗] Maybe some checkers, not all valid JSONs are desired and valid values
|
|
45422
45549
|
|
|
45550
|
+
/**
|
|
45551
|
+
* Loads the Socket.io client (`socket.io-client`) on demand
|
|
45552
|
+
*
|
|
45553
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
45554
|
+
*
|
|
45555
|
+
* @private internal utility of `createRemoteClient`
|
|
45556
|
+
*/
|
|
45557
|
+
const loadSocketIoClientModule = createLazyModuleLoader(() => import('socket.io-client'));
|
|
45423
45558
|
/**
|
|
45424
45559
|
* Creates a connection to the remote proxy server.
|
|
45425
45560
|
*
|
|
@@ -45448,6 +45583,7 @@ async function createRemoteClient(options) {
|
|
|
45448
45583
|
|
|
45449
45584
|
`));
|
|
45450
45585
|
}
|
|
45586
|
+
const { io } = await loadSocketIoClientModule();
|
|
45451
45587
|
return new Promise((resolve, reject) => {
|
|
45452
45588
|
const socket = io(remoteServerUrl, {
|
|
45453
45589
|
retries: CONNECTION_RETRIES_LIMIT,
|
|
@@ -46115,6 +46251,7 @@ async function $provideLlmToolsForCli(options) {
|
|
|
46115
46251
|
You will be logged in to ${remoteServerUrl}
|
|
46116
46252
|
If you don't have an account, it will be created automatically.
|
|
46117
46253
|
`)));
|
|
46254
|
+
const { default: prompts } = await loadPromptsModule();
|
|
46118
46255
|
const { username, password } = await prompts([
|
|
46119
46256
|
{
|
|
46120
46257
|
type: 'text',
|
|
@@ -46490,6 +46627,15 @@ function $initializeLoginCommand(program) {
|
|
|
46490
46627
|
// TODO: Implement non-interactive login
|
|
46491
46628
|
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
46492
46629
|
|
|
46630
|
+
/**
|
|
46631
|
+
* Loads the ZIP archive library (`jszip`) on demand
|
|
46632
|
+
*
|
|
46633
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
46634
|
+
*
|
|
46635
|
+
* @private internal utility of `loadArchive` and `saveArchive`
|
|
46636
|
+
*/
|
|
46637
|
+
const loadJsZipModule = createLazyModuleLoader(() => import('jszip'));
|
|
46638
|
+
|
|
46493
46639
|
/**
|
|
46494
46640
|
* Loads the books from the archive file with `.bookc` extension
|
|
46495
46641
|
*
|
|
@@ -46504,6 +46650,7 @@ async function loadArchive(filePath, fs) {
|
|
|
46504
46650
|
throw new UnexpectedError(`Archive file must have '.bookc' extension`);
|
|
46505
46651
|
}
|
|
46506
46652
|
const data = await fs.readFile(filePath);
|
|
46653
|
+
const { default: JSZip } = await loadJsZipModule();
|
|
46507
46654
|
const archive = await JSZip.loadAsync(data);
|
|
46508
46655
|
const indexFile = archive.file('index.book.json');
|
|
46509
46656
|
if (!indexFile) {
|
|
@@ -50567,7 +50714,23 @@ function createShowdownConverter() {
|
|
|
50567
50714
|
});
|
|
50568
50715
|
}
|
|
50569
50716
|
|
|
50570
|
-
|
|
50717
|
+
/**
|
|
50718
|
+
* Loads `jsdom` on demand
|
|
50719
|
+
*
|
|
50720
|
+
* Note: [🐌] `jsdom` is by far the heaviest dependency of Promptbook, loading it eagerly would slow down every single
|
|
50721
|
+
* run of the `ptbk` CLI utility even when no website is scraped
|
|
50722
|
+
*
|
|
50723
|
+
* @private internal utility of `WebsiteScraper`
|
|
50724
|
+
*/
|
|
50725
|
+
const loadJsdomModule = createLazyModuleLoader(() => import('jsdom'));
|
|
50726
|
+
/**
|
|
50727
|
+
* Loads `@mozilla/readability` on demand
|
|
50728
|
+
*
|
|
50729
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
50730
|
+
*
|
|
50731
|
+
* @private internal utility of `WebsiteScraper`
|
|
50732
|
+
*/
|
|
50733
|
+
const loadReadabilityModule = createLazyModuleLoader(() => import('@mozilla/readability'));
|
|
50571
50734
|
/**
|
|
50572
50735
|
* Scraper for websites
|
|
50573
50736
|
*
|
|
@@ -50603,6 +50766,7 @@ class WebsiteScraper {
|
|
|
50603
50766
|
if (this.tools.fs === undefined) {
|
|
50604
50767
|
throw new EnvironmentMismatchError('Can not scrape websites without filesystem tools');
|
|
50605
50768
|
}
|
|
50769
|
+
const [{ JSDOM }, { Readability }] = await Promise.all([loadJsdomModule(), loadReadabilityModule()]);
|
|
50606
50770
|
const jsdom = new JSDOM(await source.asText(), {
|
|
50607
50771
|
url: source.url,
|
|
50608
50772
|
});
|
|
@@ -54206,6 +54370,7 @@ async function saveArchive(filePath, collectionJson, fs) {
|
|
|
54206
54370
|
for (const pipelineJson of collectionJson) {
|
|
54207
54371
|
validatePipeline(pipelineJson);
|
|
54208
54372
|
}
|
|
54373
|
+
const { default: JSZip } = await loadJsZipModule();
|
|
54209
54374
|
const archive = new JSZip();
|
|
54210
54375
|
const collectionJsonString = stringifyPipelineJson(collectionJson);
|
|
54211
54376
|
archive.file('index.book.json', collectionJsonString);
|
|
@@ -54834,6 +54999,7 @@ async function runInteractiveChatbot(options) {
|
|
|
54834
54999
|
else {
|
|
54835
55000
|
console.info(colors.gray(`---`));
|
|
54836
55001
|
}
|
|
55002
|
+
const { default: prompts } = await loadPromptsModule();
|
|
54837
55003
|
const response = await prompts({
|
|
54838
55004
|
type: 'text',
|
|
54839
55005
|
name: 'userMessage',
|
|
@@ -55141,6 +55307,7 @@ async function resolveRunPipelineSource(pipelineSource) {
|
|
|
55141
55307
|
if (pipelineSource) {
|
|
55142
55308
|
return pipelineSource;
|
|
55143
55309
|
}
|
|
55310
|
+
const { default: prompts } = await loadPromptsModule();
|
|
55144
55311
|
const response = await prompts({
|
|
55145
55312
|
type: 'text',
|
|
55146
55313
|
name: 'pipelineSource',
|
|
@@ -55228,6 +55395,7 @@ async function resolveRunInputParameters(options) {
|
|
|
55228
55395
|
console.error(colors.red(createRunMissingInputParametersMessage(pipeline, inputParameters, questions)));
|
|
55229
55396
|
return process.exit(1);
|
|
55230
55397
|
}
|
|
55398
|
+
const { default: prompts } = await loadPromptsModule();
|
|
55231
55399
|
const response = await prompts(questions);
|
|
55232
55400
|
// <- TODO: [🧠][🍼] Change behavior according to the formfactor
|
|
55233
55401
|
return { ...inputParameters, ...response };
|
|
@@ -58133,6 +58301,14 @@ const ANTHROPIC_PROVIDER_PROFILE = {
|
|
|
58133
58301
|
fullname: 'Anthropic Claude',
|
|
58134
58302
|
color: '#d97706',
|
|
58135
58303
|
};
|
|
58304
|
+
/**
|
|
58305
|
+
* Loads the Anthropic Claude SDK (`@anthropic-ai/sdk`) on demand
|
|
58306
|
+
*
|
|
58307
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
58308
|
+
*
|
|
58309
|
+
* @private internal utility of `AnthropicClaudeExecutionTools`
|
|
58310
|
+
*/
|
|
58311
|
+
const loadAnthropicClaudeModule = createLazyModuleLoader(() => import('@anthropic-ai/sdk'));
|
|
58136
58312
|
/**
|
|
58137
58313
|
* Execution Tools for calling Anthropic Claude API.
|
|
58138
58314
|
*
|
|
@@ -58170,6 +58346,7 @@ class AnthropicClaudeExecutionTools {
|
|
|
58170
58346
|
const anthropicOptions = { ...this.options };
|
|
58171
58347
|
delete anthropicOptions.isVerbose;
|
|
58172
58348
|
delete anthropicOptions.isProxied;
|
|
58349
|
+
const { Anthropic } = await loadAnthropicClaudeModule();
|
|
58173
58350
|
this.client = new Anthropic(anthropicOptions);
|
|
58174
58351
|
}
|
|
58175
58352
|
return this.client;
|
|
@@ -58433,6 +58610,14 @@ const AZURE_OPENAI_PROVIDER_PROFILE = {
|
|
|
58433
58610
|
fullname: 'Azure OpenAI',
|
|
58434
58611
|
color: '#0078d4',
|
|
58435
58612
|
};
|
|
58613
|
+
/**
|
|
58614
|
+
* Loads the Azure OpenAI SDK (`@azure/openai`) on demand
|
|
58615
|
+
*
|
|
58616
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
58617
|
+
*
|
|
58618
|
+
* @private internal utility of `AzureOpenAiExecutionTools`
|
|
58619
|
+
*/
|
|
58620
|
+
const loadAzureOpenAiModule = createLazyModuleLoader(() => import('@azure/openai'));
|
|
58436
58621
|
/**
|
|
58437
58622
|
* Execution Tools for calling Azure OpenAI API.
|
|
58438
58623
|
*
|
|
@@ -58466,6 +58651,7 @@ class AzureOpenAiExecutionTools {
|
|
|
58466
58651
|
}
|
|
58467
58652
|
async getClient() {
|
|
58468
58653
|
if (this.client === null) {
|
|
58654
|
+
const { AzureKeyCredential, OpenAIClient } = await loadAzureOpenAiModule();
|
|
58469
58655
|
this.client = new OpenAIClient(`https://${this.options.resourceName}.openai.azure.com/`, new AzureKeyCredential(this.options.apiKey));
|
|
58470
58656
|
}
|
|
58471
58657
|
return this.client;
|
|
@@ -60275,6 +60461,14 @@ class OpenAiCompatibleNonChatPromptCaller {
|
|
|
60275
60461
|
}
|
|
60276
60462
|
}
|
|
60277
60463
|
|
|
60464
|
+
/**
|
|
60465
|
+
* Loads the OpenAI SDK (`openai`) on demand
|
|
60466
|
+
*
|
|
60467
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
60468
|
+
*
|
|
60469
|
+
* @private internal utility of `OpenAiCompatibleRequestManager`
|
|
60470
|
+
*/
|
|
60471
|
+
const loadOpenAiModule = createLazyModuleLoader(() => import('openai'));
|
|
60278
60472
|
/**
|
|
60279
60473
|
* Manages OpenAI-compatible client creation plus shared retry and rate-limit behavior.
|
|
60280
60474
|
*
|
|
@@ -60301,6 +60495,7 @@ class OpenAiCompatibleRequestManager {
|
|
|
60301
60495
|
timeout: API_REQUEST_TIMEOUT,
|
|
60302
60496
|
maxRetries: CONNECTION_RETRIES_LIMIT,
|
|
60303
60497
|
};
|
|
60498
|
+
const { default: OpenAI } = await loadOpenAiModule();
|
|
60304
60499
|
this.client = new OpenAI(enhancedOptions);
|
|
60305
60500
|
}
|
|
60306
60501
|
return this.client;
|
|
@@ -68014,6 +68209,7 @@ async function runAgentChat(options) {
|
|
|
68014
68209
|
if (options.isVerbose) {
|
|
68015
68210
|
console.info(colors.gray('Type "exit" or "quit" to end the chat.'));
|
|
68016
68211
|
}
|
|
68212
|
+
const { default: prompts } = await loadPromptsModule();
|
|
68017
68213
|
while (true) {
|
|
68018
68214
|
const response = await prompts({
|
|
68019
68215
|
type: 'text',
|
|
@@ -69227,6 +69423,16 @@ class OpenAiAgentKitExecutionToolsOutputTypeMapper {
|
|
|
69227
69423
|
}
|
|
69228
69424
|
}
|
|
69229
69425
|
|
|
69426
|
+
/**
|
|
69427
|
+
* Loads the OpenAI AgentKit SDK (`@openai/agents`) on demand
|
|
69428
|
+
*
|
|
69429
|
+
* Note: [🐌] The AgentKit SDK is one of the heaviest dependencies of Promptbook, loading it eagerly would slow down
|
|
69430
|
+
* every single run of the `ptbk` CLI utility even when no AgentKit agent is used
|
|
69431
|
+
*
|
|
69432
|
+
* @private internal utility of `@promptbook/openai`
|
|
69433
|
+
*/
|
|
69434
|
+
const loadOpenAiAgentsModule = createLazyModuleLoader(() => import('@openai/agents'));
|
|
69435
|
+
|
|
69230
69436
|
/**
|
|
69231
69437
|
* Constant for default model used for nested DeepSearch tool invocations.
|
|
69232
69438
|
*/
|
|
@@ -69280,8 +69486,9 @@ class OpenAiAgentKitExecutionToolsToolBuilder {
|
|
|
69280
69486
|
/**
|
|
69281
69487
|
* Builds the tool list for AgentKit, including hosted file search when applicable.
|
|
69282
69488
|
*/
|
|
69283
|
-
buildAgentKitTools(options) {
|
|
69489
|
+
async buildAgentKitTools(options) {
|
|
69284
69490
|
const { tools, vectorStoreId } = options;
|
|
69491
|
+
const { fileSearchTool, tool: agentKitTool } = await loadOpenAiAgentsModule();
|
|
69285
69492
|
const agentKitTools = [];
|
|
69286
69493
|
if (vectorStoreId) {
|
|
69287
69494
|
agentKitTools.push(fileSearchTool(vectorStoreId));
|
|
@@ -69292,11 +69499,11 @@ class OpenAiAgentKitExecutionToolsToolBuilder {
|
|
|
69292
69499
|
let scriptTools = null;
|
|
69293
69500
|
for (const toolDefinition of tools) {
|
|
69294
69501
|
if (this.isDeepSearchToolDefinition(toolDefinition)) {
|
|
69295
|
-
agentKitTools.push(this.createDeepSearchAgentKitTool(toolDefinition));
|
|
69502
|
+
agentKitTools.push(await this.createDeepSearchAgentKitTool(toolDefinition));
|
|
69296
69503
|
continue;
|
|
69297
69504
|
}
|
|
69298
69505
|
scriptTools !== null && scriptTools !== void 0 ? scriptTools : (scriptTools = this.resolveScriptTools());
|
|
69299
|
-
agentKitTools.push(
|
|
69506
|
+
agentKitTools.push(agentKitTool({
|
|
69300
69507
|
name: toolDefinition.name,
|
|
69301
69508
|
description: toolDefinition.description,
|
|
69302
69509
|
parameters: this.normalizeAgentKitToolParameters(toolDefinition.parameters),
|
|
@@ -69503,8 +69710,9 @@ class OpenAiAgentKitExecutionToolsToolBuilder {
|
|
|
69503
69710
|
/**
|
|
69504
69711
|
* Creates the native Agent SDK tool used for `USE DEEPSEARCH`.
|
|
69505
69712
|
*/
|
|
69506
|
-
createDeepSearchAgentKitTool(toolDefinition) {
|
|
69507
|
-
const
|
|
69713
|
+
async createDeepSearchAgentKitTool(toolDefinition) {
|
|
69714
|
+
const { Agent: AgentFromKit, webSearchTool } = await loadOpenAiAgentsModule();
|
|
69715
|
+
const deepSearchAgent = new AgentFromKit({
|
|
69508
69716
|
name: 'DeepSearch',
|
|
69509
69717
|
model: DEFAULT_DEEP_SEARCH_MODEL_NAME,
|
|
69510
69718
|
instructions: this.createDeepSearchAgentInstructions(toolDefinition.description),
|
|
@@ -69717,8 +69925,9 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
|
|
|
69717
69925
|
vectorStoreId,
|
|
69718
69926
|
});
|
|
69719
69927
|
}
|
|
69720
|
-
const
|
|
69721
|
-
const
|
|
69928
|
+
const { Agent: AgentFromKit } = await loadOpenAiAgentsModule();
|
|
69929
|
+
const agentKitTools = await this.buildAgentKitTools({ tools, vectorStoreId });
|
|
69930
|
+
const openAiAgentKitAgent = new AgentFromKit({
|
|
69722
69931
|
name,
|
|
69723
69932
|
model: this.agentKitModelName,
|
|
69724
69933
|
instructions: instructions || 'You are a helpful assistant.',
|
|
@@ -69763,6 +69972,7 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
|
|
|
69763
69972
|
agentName: agentForRun.name,
|
|
69764
69973
|
input: inputItems,
|
|
69765
69974
|
};
|
|
69975
|
+
const { run } = await loadOpenAiAgentsModule();
|
|
69766
69976
|
const streamResult = await run(agentForRun, inputItems, {
|
|
69767
69977
|
stream: true,
|
|
69768
69978
|
maxTurns: 200,
|
|
@@ -69905,6 +70115,7 @@ class OpenAiAgentKitExecutionTools extends OpenAiVectorStoreHandler {
|
|
|
69905
70115
|
* Ensures the AgentKit SDK is wired to the OpenAI client and API key.
|
|
69906
70116
|
*/
|
|
69907
70117
|
async ensureAgentKitDefaults() {
|
|
70118
|
+
const { setDefaultOpenAIClient, setDefaultOpenAIKey } = await loadOpenAiAgentsModule();
|
|
69908
70119
|
const client = await this.getClient();
|
|
69909
70120
|
setDefaultOpenAIClient(client);
|
|
69910
70121
|
const apiKey = this.agentKitOptions.apiKey;
|
|
@@ -72237,6 +72448,66 @@ var RemoteAgent$1 = /*#__PURE__*/Object.freeze({
|
|
|
72237
72448
|
RemoteAgent: RemoteAgent
|
|
72238
72449
|
});
|
|
72239
72450
|
|
|
72451
|
+
/**
|
|
72452
|
+
* Git synchronization which leaves the repository completely untouched.
|
|
72453
|
+
*
|
|
72454
|
+
* Note: This is the default for every command and helper which supports the git synchronization.
|
|
72455
|
+
*/
|
|
72456
|
+
const DISABLED_CODER_GIT_SYNC_OPTIONS = Object.freeze({
|
|
72457
|
+
isCommitEnabled: false,
|
|
72458
|
+
isAutoPushEnabled: false,
|
|
72459
|
+
isAutoPullEnabled: false,
|
|
72460
|
+
});
|
|
72461
|
+
/**
|
|
72462
|
+
* Pulls the latest repository changes before a `ptbk coder` command changes the project.
|
|
72463
|
+
*/
|
|
72464
|
+
async function $pullCoderChanges(options) {
|
|
72465
|
+
const { gitSync, projectPath = process.cwd() } = options;
|
|
72466
|
+
if (!gitSync.isAutoPullEnabled) {
|
|
72467
|
+
return;
|
|
72468
|
+
}
|
|
72469
|
+
console.info(colors.gray('Pulling the latest changes from the remote repository...'));
|
|
72470
|
+
await pullLatestChanges(projectPath);
|
|
72471
|
+
}
|
|
72472
|
+
/**
|
|
72473
|
+
* Commits - and when requested also pushes - the changes one `ptbk coder` command has just made.
|
|
72474
|
+
*
|
|
72475
|
+
* Note: A repository without any change is left alone instead of creating an empty commit.
|
|
72476
|
+
*/
|
|
72477
|
+
async function $commitCoderChanges(options) {
|
|
72478
|
+
const { gitSync, commitMessage, projectPath = process.cwd() } = options;
|
|
72479
|
+
if (!gitSync.isCommitEnabled) {
|
|
72480
|
+
return;
|
|
72481
|
+
}
|
|
72482
|
+
if (!(await hasChangesToCommit(projectPath))) {
|
|
72483
|
+
console.info(colors.gray('Nothing to commit, the working tree is clean'));
|
|
72484
|
+
return;
|
|
72485
|
+
}
|
|
72486
|
+
await commitChanges(commitMessage, {
|
|
72487
|
+
projectPath,
|
|
72488
|
+
autoPush: gitSync.isAutoPushEnabled,
|
|
72489
|
+
});
|
|
72490
|
+
console.info(colors.green(`✓ ${gitSync.isAutoPushEnabled ? 'Committed and pushed' : 'Committed'}: ${commitMessage}`));
|
|
72491
|
+
}
|
|
72492
|
+
/**
|
|
72493
|
+
* Checks whether the repository holds any change which can be committed.
|
|
72494
|
+
*/
|
|
72495
|
+
async function hasChangesToCommit(projectPath) {
|
|
72496
|
+
const gitStatus = await runGitCommand({
|
|
72497
|
+
command: 'git status --porcelain',
|
|
72498
|
+
cwd: projectPath,
|
|
72499
|
+
isVerbose: false,
|
|
72500
|
+
});
|
|
72501
|
+
return gitStatus.trim() !== '';
|
|
72502
|
+
}
|
|
72503
|
+
|
|
72504
|
+
var coderGitSync = /*#__PURE__*/Object.freeze({
|
|
72505
|
+
__proto__: null,
|
|
72506
|
+
DISABLED_CODER_GIT_SYNC_OPTIONS: DISABLED_CODER_GIT_SYNC_OPTIONS,
|
|
72507
|
+
$pullCoderChanges: $pullCoderChanges,
|
|
72508
|
+
$commitCoderChanges: $commitCoderChanges
|
|
72509
|
+
});
|
|
72510
|
+
|
|
72240
72511
|
/**
|
|
72241
72512
|
* Calculates the next available prompt numbering sequence for a month.
|
|
72242
72513
|
*/
|
|
@@ -72711,6 +72982,31 @@ function normalizeRefactorCandidatePath(pathValue) {
|
|
|
72711
72982
|
}
|
|
72712
72983
|
// Note: [🟡] Code for repository script [normalizeRefactorCandidatePath](scripts/find-refactor-candidates/normalizeRefactorCandidatePath.ts) should never be published outside of `@promptbook/cli`
|
|
72713
72984
|
|
|
72985
|
+
/**
|
|
72986
|
+
* The TypeScript compiler API once it was loaded by `analyzeSourceFileForRefactorCandidate`
|
|
72987
|
+
*
|
|
72988
|
+
* Note: [🐌] `typescript` is a heavy package, it is loaded on demand so that it does not slow down every single run
|
|
72989
|
+
* of the `ptbk` CLI utility
|
|
72990
|
+
*
|
|
72991
|
+
* @private variable of analyzeSourceFileForRefactorCandidate
|
|
72992
|
+
*/
|
|
72993
|
+
let loadedTypescriptModule = null;
|
|
72994
|
+
/**
|
|
72995
|
+
* Returns the TypeScript compiler API which was already loaded for the structural analysis.
|
|
72996
|
+
*
|
|
72997
|
+
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72998
|
+
*/
|
|
72999
|
+
function getLoadedTypescriptModule() {
|
|
73000
|
+
if (loadedTypescriptModule === null) {
|
|
73001
|
+
throw new UnexpectedError(spaceTrim(`
|
|
73002
|
+
The \`typescript\` module was not loaded yet.
|
|
73003
|
+
|
|
73004
|
+
Structural analysis helpers must be called only from \`analyzeSourceFileForRefactorCandidate\` which
|
|
73005
|
+
loads \`typescript\` lazily.
|
|
73006
|
+
`));
|
|
73007
|
+
}
|
|
73008
|
+
return loadedTypescriptModule;
|
|
73009
|
+
}
|
|
72714
73010
|
/**
|
|
72715
73011
|
* Resolves whether a source file should produce a refactor candidate entry.
|
|
72716
73012
|
*
|
|
@@ -72736,6 +73032,7 @@ async function analyzeSourceFileForRefactorCandidate(options) {
|
|
|
72736
73032
|
}
|
|
72737
73033
|
}
|
|
72738
73034
|
if (STRUCTURAL_ANALYSIS_EXTENSIONS.includes(extension)) {
|
|
73035
|
+
loadedTypescriptModule !== null && loadedTypescriptModule !== void 0 ? loadedTypescriptModule : (loadedTypescriptModule = await getTypescriptModule());
|
|
72739
73036
|
const structureSummary = summarizeSourceFileStructure(content, extension, filePath);
|
|
72740
73037
|
if (structureSummary.entityCount > heuristics.maxEntityCountPerFile) {
|
|
72741
73038
|
reasons.push(`entities ${structureSummary.entityCount}/${heuristics.maxEntityCountPerFile}`);
|
|
@@ -72795,6 +73092,7 @@ function countLines(content) {
|
|
|
72795
73092
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72796
73093
|
*/
|
|
72797
73094
|
function summarizeSourceFileStructure(content, extension, filePath) {
|
|
73095
|
+
const ts = getLoadedTypescriptModule();
|
|
72798
73096
|
const scriptKind = getScriptKindForExtension(extension);
|
|
72799
73097
|
const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true, scriptKind);
|
|
72800
73098
|
return {
|
|
@@ -72808,6 +73106,7 @@ function summarizeSourceFileStructure(content, extension, filePath) {
|
|
|
72808
73106
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72809
73107
|
*/
|
|
72810
73108
|
function countEntitiesInSourceFile(sourceFile) {
|
|
73109
|
+
const ts = getLoadedTypescriptModule();
|
|
72811
73110
|
let count = 0;
|
|
72812
73111
|
// Only count top-level declarations to avoid inflating with members or nested scopes.
|
|
72813
73112
|
for (const statement of sourceFile.statements) {
|
|
@@ -72840,6 +73139,7 @@ function countEntitiesInSourceFile(sourceFile) {
|
|
|
72840
73139
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72841
73140
|
*/
|
|
72842
73141
|
function summarizeFunctionsInSourceFile(sourceFile) {
|
|
73142
|
+
const ts = getLoadedTypescriptModule();
|
|
72843
73143
|
let functionCount = 0;
|
|
72844
73144
|
let maxFunctionComplexity = 0;
|
|
72845
73145
|
let mostComplexFunctionName = null;
|
|
@@ -72867,6 +73167,7 @@ function summarizeFunctionsInSourceFile(sourceFile) {
|
|
|
72867
73167
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72868
73168
|
*/
|
|
72869
73169
|
function isCountedFunctionLikeDeclaration(node) {
|
|
73170
|
+
const ts = getLoadedTypescriptModule();
|
|
72870
73171
|
if (ts.isFunctionDeclaration(node) ||
|
|
72871
73172
|
ts.isMethodDeclaration(node) ||
|
|
72872
73173
|
ts.isConstructorDeclaration(node) ||
|
|
@@ -72885,6 +73186,7 @@ function isCountedFunctionLikeDeclaration(node) {
|
|
|
72885
73186
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72886
73187
|
*/
|
|
72887
73188
|
function isNamedFunctionExpression(node) {
|
|
73189
|
+
const ts = getLoadedTypescriptModule();
|
|
72888
73190
|
const parent = node.parent;
|
|
72889
73191
|
return (ts.isVariableDeclaration(parent) || ts.isPropertyDeclaration(parent) || ts.isPropertyAssignment(parent));
|
|
72890
73192
|
}
|
|
@@ -72897,6 +73199,7 @@ function calculateFunctionComplexity(functionNode) {
|
|
|
72897
73199
|
if (!functionNode.body) {
|
|
72898
73200
|
return 1;
|
|
72899
73201
|
}
|
|
73202
|
+
const ts = getLoadedTypescriptModule();
|
|
72900
73203
|
let complexity = 1;
|
|
72901
73204
|
const visitNode = (node) => {
|
|
72902
73205
|
if (node !== functionNode.body && isCountedFunctionLikeDeclaration(node)) {
|
|
@@ -72916,6 +73219,7 @@ function calculateFunctionComplexity(functionNode) {
|
|
|
72916
73219
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72917
73220
|
*/
|
|
72918
73221
|
function isComplexityDecisionNode(node) {
|
|
73222
|
+
const ts = getLoadedTypescriptModule();
|
|
72919
73223
|
if (ts.isIfStatement(node) ||
|
|
72920
73224
|
ts.isConditionalExpression(node) ||
|
|
72921
73225
|
ts.isCatchClause(node) ||
|
|
@@ -72941,6 +73245,7 @@ function isComplexityDecisionNode(node) {
|
|
|
72941
73245
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72942
73246
|
*/
|
|
72943
73247
|
function getFunctionDisplayName(functionNode) {
|
|
73248
|
+
const ts = getLoadedTypescriptModule();
|
|
72944
73249
|
if (ts.isConstructorDeclaration(functionNode)) {
|
|
72945
73250
|
return 'constructor';
|
|
72946
73251
|
}
|
|
@@ -72973,6 +73278,7 @@ function getFunctionDisplayName(functionNode) {
|
|
|
72973
73278
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72974
73279
|
*/
|
|
72975
73280
|
function getBindingNameText(name) {
|
|
73281
|
+
const ts = getLoadedTypescriptModule();
|
|
72976
73282
|
return ts.isIdentifier(name) ? name.text : null;
|
|
72977
73283
|
}
|
|
72978
73284
|
/**
|
|
@@ -72981,6 +73287,7 @@ function getBindingNameText(name) {
|
|
|
72981
73287
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
72982
73288
|
*/
|
|
72983
73289
|
function getPropertyNameText(name) {
|
|
73290
|
+
const ts = getLoadedTypescriptModule();
|
|
72984
73291
|
if (ts.isIdentifier(name) || ts.isPrivateIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name)) {
|
|
72985
73292
|
return name.text;
|
|
72986
73293
|
}
|
|
@@ -73003,6 +73310,7 @@ function buildComplexityReason(structureSummary, maxAllowedFunctionComplexity) {
|
|
|
73003
73310
|
* @private function of analyzeSourceFileForRefactorCandidate
|
|
73004
73311
|
*/
|
|
73005
73312
|
function getScriptKindForExtension(extension) {
|
|
73313
|
+
const ts = getLoadedTypescriptModule();
|
|
73006
73314
|
if (extension === '.tsx') {
|
|
73007
73315
|
return ts.ScriptKind.TSX;
|
|
73008
73316
|
}
|
|
@@ -73862,63 +74170,240 @@ var findUnwrittenPrompts$1 = /*#__PURE__*/Object.freeze({
|
|
|
73862
74170
|
});
|
|
73863
74171
|
|
|
73864
74172
|
/**
|
|
73865
|
-
*
|
|
74173
|
+
* Builds a normalized temporary shell script path for prompt runners.
|
|
73866
74174
|
*/
|
|
73867
|
-
|
|
73868
|
-
|
|
74175
|
+
function buildTemporaryPromptScriptPath(options) {
|
|
74176
|
+
const sourceFileName = basename(options.sourceFileName);
|
|
74177
|
+
const scriptFileName = `${sourceFileName.replace(/\.[^.]+$/u, '')}${options.suffix || ''}.sh`;
|
|
74178
|
+
return resolvePromptbookTemporaryPath(options.projectPath, options.scriptDirectoryName, scriptFileName);
|
|
74179
|
+
}
|
|
73869
74180
|
|
|
73870
|
-
PERSONA You are a connectivity test agent. Perform only the tiny task requested by the user and answer concisely.
|
|
73871
|
-
`);
|
|
73872
74181
|
/**
|
|
73873
|
-
*
|
|
74182
|
+
* Marker the pinged harness is asked to prefix its answer with, so the reply can be recognized
|
|
74183
|
+
* in the raw runner output of every supported harness.
|
|
74184
|
+
*
|
|
74185
|
+
* Note: The marker must stay free of regular-expression metacharacters, because
|
|
74186
|
+
* `extractCoderPingAnswer` builds its pattern from it.
|
|
74187
|
+
*/
|
|
74188
|
+
const CODER_PING_ANSWER_MARKER = 'PTBK-CODER-PING-ANSWER';
|
|
74189
|
+
/**
|
|
74190
|
+
* First factor of the dummy multiplication the pinged harness is asked to compute.
|
|
74191
|
+
*/
|
|
74192
|
+
const CODER_PING_FIRST_FACTOR = 6;
|
|
74193
|
+
/**
|
|
74194
|
+
* Second factor of the dummy multiplication the pinged harness is asked to compute.
|
|
73874
74195
|
*/
|
|
73875
|
-
const
|
|
74196
|
+
const CODER_PING_SECOND_FACTOR = 7;
|
|
73876
74197
|
/**
|
|
73877
|
-
*
|
|
74198
|
+
* Answer a working harness and model returns for the dummy work of `ptbk coder ping`.
|
|
74199
|
+
*/
|
|
74200
|
+
const CODER_PING_EXPECTED_ANSWER = String(CODER_PING_FIRST_FACTOR * CODER_PING_SECOND_FACTOR);
|
|
74201
|
+
/**
|
|
74202
|
+
* Builds the dummy prompt sent by `ptbk coder ping`.
|
|
73878
74203
|
*
|
|
73879
|
-
* The
|
|
73880
|
-
*
|
|
73881
|
-
*
|
|
74204
|
+
* The work is intentionally the smallest possible one that still reaches the model: it spends a
|
|
74205
|
+
* negligible amount of the harness quota, it needs no tool and it explicitly forbids touching the
|
|
74206
|
+
* project, so a ping leaves the project exactly as it was.
|
|
73882
74207
|
*/
|
|
73883
|
-
|
|
73884
|
-
|
|
73885
|
-
|
|
73886
|
-
|
|
73887
|
-
|
|
73888
|
-
|
|
73889
|
-
|
|
73890
|
-
|
|
73891
|
-
|
|
73892
|
-
|
|
73893
|
-
|
|
73894
|
-
|
|
73895
|
-
|
|
73896
|
-
|
|
73897
|
-
|
|
73898
|
-
|
|
73899
|
-
|
|
73900
|
-
|
|
73901
|
-
|
|
73902
|
-
|
|
73903
|
-
|
|
73904
|
-
|
|
73905
|
-
|
|
73906
|
-
|
|
74208
|
+
function buildCoderPingPrompt() {
|
|
74209
|
+
return spaceTrim(`
|
|
74210
|
+
# Promptbook connection check
|
|
74211
|
+
|
|
74212
|
+
This is an automated \`ptbk coder ping\` connection check, not a coding task.
|
|
74213
|
+
|
|
74214
|
+
Do exactly this and nothing else:
|
|
74215
|
+
|
|
74216
|
+
1. Multiply \`${CODER_PING_FIRST_FACTOR}\` by \`${CODER_PING_SECOND_FACTOR}\`.
|
|
74217
|
+
2. Answer with one single line \`${CODER_PING_ANSWER_MARKER}: <result>\` where \`<result>\` is the number you computed.
|
|
74218
|
+
|
|
74219
|
+
Rules:
|
|
74220
|
+
|
|
74221
|
+
- Do not read, create, change, move or delete any file.
|
|
74222
|
+
- Do not run any command and do not use any tool.
|
|
74223
|
+
- Do not write anything except the single answer line.
|
|
74224
|
+
`);
|
|
74225
|
+
}
|
|
74226
|
+
|
|
74227
|
+
/**
|
|
74228
|
+
* Pattern matching one answer line produced by the pinged harness.
|
|
74229
|
+
*
|
|
74230
|
+
* The captured answer deliberately stops at a quote, a backslash or a line break, so an answer
|
|
74231
|
+
* embedded in a JSON event stream — as produced by Claude Code, Opencode or Codex `--json` — is
|
|
74232
|
+
* captured without the surrounding JSON.
|
|
74233
|
+
*/
|
|
74234
|
+
const CODER_PING_ANSWER_PATTERN = new RegExp(`${CODER_PING_ANSWER_MARKER}\\s*:[ \\t]*([^\\r\\n"\\\\]*)`, 'gu');
|
|
74235
|
+
/**
|
|
74236
|
+
* Extracts the answer of a pinged harness from the runtime log of its runner shell.
|
|
74237
|
+
*
|
|
74238
|
+
* Only the raw output of the last execution is searched, so the answer marker contained in the
|
|
74239
|
+
* prompt of the raw input is never mistaken for the answer of the harness.
|
|
74240
|
+
*
|
|
74241
|
+
* @returns The answer of the harness, or `null` when the harness produced no recognizable answer
|
|
74242
|
+
*/
|
|
74243
|
+
function extractCoderPingAnswer(runtimeLog) {
|
|
74244
|
+
var _a;
|
|
74245
|
+
const rawOutput = runtimeLog.split(SCRIPT_EXECUTION_LOG_RAW_OUTPUT_MARKER).pop();
|
|
74246
|
+
if (rawOutput === undefined) {
|
|
74247
|
+
return null;
|
|
74248
|
+
}
|
|
74249
|
+
// Note: The last answer wins because harnesses which stream partial messages repeat the growing answer line
|
|
74250
|
+
const answers = Array.from(rawOutput.matchAll(CODER_PING_ANSWER_PATTERN))
|
|
74251
|
+
.map((match) => (match[1] || '').trim())
|
|
74252
|
+
.filter((answer) => answer !== '');
|
|
74253
|
+
return (_a = answers[answers.length - 1]) !== null && _a !== void 0 ? _a : null;
|
|
74254
|
+
}
|
|
74255
|
+
|
|
74256
|
+
/**
|
|
74257
|
+
* Temporary subdirectory used for the `ptbk coder ping` runner shell script and its runtime log.
|
|
74258
|
+
*/
|
|
74259
|
+
const CODER_PING_SCRIPT_DIRECTORY_NAME = 'coder-ping';
|
|
74260
|
+
/**
|
|
74261
|
+
* Base name of the temporary `ptbk coder ping` runner shell script.
|
|
74262
|
+
*/
|
|
74263
|
+
const CODER_PING_SCRIPT_SOURCE_NAME = 'ping';
|
|
74264
|
+
/**
|
|
74265
|
+
* Sends one tiny dummy prompt through the selected harness and model and measures the round trip.
|
|
74266
|
+
*
|
|
74267
|
+
* The ping reuses the very same runner the coding queue uses, so it really exercises the configured
|
|
74268
|
+
* harness, model, thinking level and authentication — including the retry behavior on rate limits.
|
|
74269
|
+
* Both temporary artifacts it creates are removed again, so the project is left as it was.
|
|
74270
|
+
*/
|
|
74271
|
+
async function pingCoderHarness(options) {
|
|
74272
|
+
const projectPath = options.projectPath || process.cwd();
|
|
74273
|
+
const { runner, runnerMetadata } = resolvePromptRunner(options);
|
|
74274
|
+
const scriptPath = buildTemporaryPromptScriptPath({
|
|
74275
|
+
projectPath,
|
|
74276
|
+
scriptDirectoryName: CODER_PING_SCRIPT_DIRECTORY_NAME,
|
|
74277
|
+
sourceFileName: CODER_PING_SCRIPT_SOURCE_NAME,
|
|
74278
|
+
});
|
|
74279
|
+
const startedTimeMs = Date.now();
|
|
74280
|
+
const { answer, usage, loginMethod } = await withPromptRuntimeLog(scriptPath, async (logPath) => {
|
|
74281
|
+
var _a;
|
|
74282
|
+
const result = await runner.runPrompt({
|
|
74283
|
+
prompt: buildCoderPingPrompt(),
|
|
74284
|
+
scriptPath,
|
|
74285
|
+
projectPath,
|
|
74286
|
+
logPath,
|
|
74287
|
+
shouldPrintLiveOutput: (_a = options.shouldPrintLiveOutput) !== null && _a !== void 0 ? _a : false,
|
|
74288
|
+
preserveArtifactsOnSuccess: false,
|
|
73907
74289
|
});
|
|
73908
|
-
return {
|
|
73909
|
-
|
|
73910
|
-
|
|
73911
|
-
|
|
74290
|
+
return { ...result, answer: extractCoderPingAnswer(await readRuntimeLog(logPath)) };
|
|
74291
|
+
}, { preserveArtifactsOnSuccess: false });
|
|
74292
|
+
return {
|
|
74293
|
+
runnerName: runnerMetadata.runnerName,
|
|
74294
|
+
modelName: runnerMetadata.modelName,
|
|
74295
|
+
thinkingLevel: options.thinkingLevel,
|
|
74296
|
+
answer,
|
|
74297
|
+
isAnswerCorrect: answer === CODER_PING_EXPECTED_ANSWER,
|
|
74298
|
+
durationMs: Date.now() - startedTimeMs,
|
|
74299
|
+
usage,
|
|
74300
|
+
loginMethod,
|
|
74301
|
+
};
|
|
74302
|
+
}
|
|
74303
|
+
/**
|
|
74304
|
+
* Reads the runtime log of the finished ping, treating an unreadable log as no output at all.
|
|
74305
|
+
*/
|
|
74306
|
+
async function readRuntimeLog(logPath) {
|
|
74307
|
+
return await readFile(logPath, 'utf-8').catch(() => '');
|
|
74308
|
+
}
|
|
74309
|
+
|
|
74310
|
+
var pingCoderHarness$1 = /*#__PURE__*/Object.freeze({
|
|
74311
|
+
__proto__: null,
|
|
74312
|
+
pingCoderHarness: pingCoderHarness
|
|
74313
|
+
});
|
|
74314
|
+
|
|
74315
|
+
/**
|
|
74316
|
+
* Formats usage price for display in prompt status lines and task details.
|
|
74317
|
+
* Examples:
|
|
74318
|
+
* - "$0.12" (certain)
|
|
74319
|
+
* - "~$3.05" (uncertain)
|
|
74320
|
+
* - "$0.00" (zero cost)
|
|
74321
|
+
* - "<$0.01" (tiny non-zero cost)
|
|
74322
|
+
*
|
|
74323
|
+
* @private internal utility of the prompt runners and the Agents Server task details
|
|
74324
|
+
*/
|
|
74325
|
+
function formatUsagePrice(usage) {
|
|
74326
|
+
const price = usage.price.value;
|
|
74327
|
+
const isUncertain = usage.price.isUncertain === true;
|
|
74328
|
+
const prefix = isUncertain ? '~' : '';
|
|
74329
|
+
if (price === 0) {
|
|
74330
|
+
return `${prefix}$0.00`;
|
|
73912
74331
|
}
|
|
73913
|
-
|
|
73914
|
-
|
|
73915
|
-
await rm(temporaryProjectPath, { recursive: true, force: true });
|
|
74332
|
+
if (price < 0.01) {
|
|
74333
|
+
return `${prefix}<$0.01`;
|
|
73916
74334
|
}
|
|
74335
|
+
if (price < 1) {
|
|
74336
|
+
return `${prefix}$${price.toFixed(4)}`;
|
|
74337
|
+
}
|
|
74338
|
+
return `${prefix}$${price.toFixed(2)}`;
|
|
73917
74339
|
}
|
|
73918
74340
|
|
|
73919
|
-
|
|
74341
|
+
/**
|
|
74342
|
+
* Formats runner details for prompt status lines.
|
|
74343
|
+
*/
|
|
74344
|
+
function formatRunnerSignature(runnerName, modelName, thinkingLevel) {
|
|
74345
|
+
const normalizedRunner = runnerName === null || runnerName === void 0 ? void 0 : runnerName.trim();
|
|
74346
|
+
const normalizedModel = modelName === null || modelName === void 0 ? void 0 : modelName.trim();
|
|
74347
|
+
const thinkingLevelSuffix = thinkingLevel ? ` thinking \`${thinkingLevel}\`` : '';
|
|
74348
|
+
if (!normalizedRunner && !normalizedModel) {
|
|
74349
|
+
return 'unknown';
|
|
74350
|
+
}
|
|
74351
|
+
const runnerLabel = normalizedRunner || 'unknown';
|
|
74352
|
+
if (!normalizedModel) {
|
|
74353
|
+
return `${runnerLabel}${thinkingLevelSuffix}`;
|
|
74354
|
+
}
|
|
74355
|
+
return `${runnerLabel} \`${normalizedModel}\`${thinkingLevelSuffix}`;
|
|
74356
|
+
}
|
|
74357
|
+
|
|
74358
|
+
/**
|
|
74359
|
+
* Prints the compact summary of one finished `ptbk coder ping`.
|
|
74360
|
+
*/
|
|
74361
|
+
function printCoderPingResult(result) {
|
|
74362
|
+
const runnerSignature = formatRunnerSignature(result.runnerName, result.modelName, result.thinkingLevel);
|
|
74363
|
+
const loginMethodLabel = formatCodexLoginMethod(result.loginMethod);
|
|
74364
|
+
const loginMethodSuffix = loginMethodLabel === undefined ? '' : ` (${loginMethodLabel})`;
|
|
74365
|
+
console.info(colors.green(`🏓 ${runnerSignature}${loginMethodSuffix} answered in ${formatCoderPingResponseTime(result.durationMs)}`));
|
|
74366
|
+
console.info(colors.gray(` Answer: ${formatCoderPingAnswer(result)}`));
|
|
74367
|
+
console.info(colors.gray(` Usage: ${formatCoderPingUsage(result.usage)}`));
|
|
74368
|
+
}
|
|
74369
|
+
/**
|
|
74370
|
+
* Formats the measured round-trip time, keeping the sub-second precision a response time needs.
|
|
74371
|
+
*/
|
|
74372
|
+
function formatCoderPingResponseTime(durationMs) {
|
|
74373
|
+
return `${(durationMs / 1000).toFixed(2)}s`;
|
|
74374
|
+
}
|
|
74375
|
+
/**
|
|
74376
|
+
* Formats the answer of the pinged harness together with what was expected from it.
|
|
74377
|
+
*/
|
|
74378
|
+
function formatCoderPingAnswer(result) {
|
|
74379
|
+
if (result.answer === null) {
|
|
74380
|
+
return `Reached, but the answer line was missing from the output (expected \`${CODER_PING_EXPECTED_ANSWER}\`)`;
|
|
74381
|
+
}
|
|
74382
|
+
if (result.isAnswerCorrect) {
|
|
74383
|
+
return result.answer;
|
|
74384
|
+
}
|
|
74385
|
+
return `${result.answer} (expected \`${CODER_PING_EXPECTED_ANSWER}\`)`;
|
|
74386
|
+
}
|
|
74387
|
+
/**
|
|
74388
|
+
* Formats the resources the pinged harness reported for the dummy work.
|
|
74389
|
+
*/
|
|
74390
|
+
function formatCoderPingUsage(usage) {
|
|
74391
|
+
return [
|
|
74392
|
+
formatUsagePrice(usage),
|
|
74393
|
+
`${formatUncertainCount(usage.input.tokensCount)} input tokens`,
|
|
74394
|
+
`${formatUncertainCount(usage.output.tokensCount)} output tokens`,
|
|
74395
|
+
].join(', ');
|
|
74396
|
+
}
|
|
74397
|
+
/**
|
|
74398
|
+
* Formats one counted usage value, marking an estimated count with a leading `~`.
|
|
74399
|
+
*/
|
|
74400
|
+
function formatUncertainCount(count) {
|
|
74401
|
+
return `${count.isUncertain === true ? '~' : ''}${Math.round(count.value)}`;
|
|
74402
|
+
}
|
|
74403
|
+
|
|
74404
|
+
var printCoderPingResult$1 = /*#__PURE__*/Object.freeze({
|
|
73920
74405
|
__proto__: null,
|
|
73921
|
-
|
|
74406
|
+
printCoderPingResult: printCoderPingResult
|
|
73922
74407
|
});
|
|
73923
74408
|
|
|
73924
74409
|
/**
|
|
@@ -75833,6 +76318,14 @@ function splitSqlStatements(sql) {
|
|
|
75833
76318
|
.filter((statement) => statement !== '');
|
|
75834
76319
|
}
|
|
75835
76320
|
|
|
76321
|
+
/**
|
|
76322
|
+
* Loads the PostgreSQL client (`pg`) on demand
|
|
76323
|
+
*
|
|
76324
|
+
* Note: [🐌] Loaded lazily to keep the startup of the `ptbk` CLI utility fast
|
|
76325
|
+
*
|
|
76326
|
+
* @private function of runAutoMigrateTestingServers
|
|
76327
|
+
*/
|
|
76328
|
+
const loadPostgresModule = createLazyModuleLoader(() => import('pg'));
|
|
75836
76329
|
/**
|
|
75837
76330
|
* Migration targets for testing servers that should be migrated by coding-script auto-migration.
|
|
75838
76331
|
*/
|
|
@@ -75910,6 +76403,7 @@ async function runAutoMigrateTestingServersImmediately(options) {
|
|
|
75910
76403
|
* @returns Pending migration files grouped by prefix.
|
|
75911
76404
|
*/
|
|
75912
76405
|
async function listPendingMigrationsByPrefix(options) {
|
|
76406
|
+
const { Client } = await loadPostgresModule();
|
|
75913
76407
|
const client = new Client({
|
|
75914
76408
|
connectionString: options.connectionString,
|
|
75915
76409
|
ssl: { rejectUnauthorized: false },
|
|
@@ -76067,15 +76561,6 @@ function buildCommitMessage(file, section) {
|
|
|
76067
76561
|
return lines.join(file.eol);
|
|
76068
76562
|
}
|
|
76069
76563
|
|
|
76070
|
-
/**
|
|
76071
|
-
* Builds a normalized temporary shell script path for prompt runners.
|
|
76072
|
-
*/
|
|
76073
|
-
function buildTemporaryPromptScriptPath(options) {
|
|
76074
|
-
const sourceFileName = basename(options.sourceFileName);
|
|
76075
|
-
const scriptFileName = `${sourceFileName.replace(/\.[^.]+$/u, '')}${options.suffix || ''}.sh`;
|
|
76076
|
-
return resolvePromptbookTemporaryPath(options.projectPath, options.scriptDirectoryName, scriptFileName);
|
|
76077
|
-
}
|
|
76078
|
-
|
|
76079
76564
|
/**
|
|
76080
76565
|
* Builds the suffix which disambiguates one prompt section inside its prompt file.
|
|
76081
76566
|
*
|
|
@@ -76102,32 +76587,6 @@ function buildScriptPath(file, section, projectPath = process.cwd()) {
|
|
|
76102
76587
|
});
|
|
76103
76588
|
}
|
|
76104
76589
|
|
|
76105
|
-
/**
|
|
76106
|
-
* Formats usage price for display in prompt status lines and task details.
|
|
76107
|
-
* Examples:
|
|
76108
|
-
* - "$0.12" (certain)
|
|
76109
|
-
* - "~$3.05" (uncertain)
|
|
76110
|
-
* - "$0.00" (zero cost)
|
|
76111
|
-
* - "<$0.01" (tiny non-zero cost)
|
|
76112
|
-
*
|
|
76113
|
-
* @private internal utility of the prompt runners and the Agents Server task details
|
|
76114
|
-
*/
|
|
76115
|
-
function formatUsagePrice(usage) {
|
|
76116
|
-
const price = usage.price.value;
|
|
76117
|
-
const isUncertain = usage.price.isUncertain === true;
|
|
76118
|
-
const prefix = isUncertain ? '~' : '';
|
|
76119
|
-
if (price === 0) {
|
|
76120
|
-
return `${prefix}$0.00`;
|
|
76121
|
-
}
|
|
76122
|
-
if (price < 0.01) {
|
|
76123
|
-
return `${prefix}<$0.01`;
|
|
76124
|
-
}
|
|
76125
|
-
if (price < 1) {
|
|
76126
|
-
return `${prefix}$${price.toFixed(4)}`;
|
|
76127
|
-
}
|
|
76128
|
-
return `${prefix}$${price.toFixed(2)}`;
|
|
76129
|
-
}
|
|
76130
|
-
|
|
76131
76590
|
/**
|
|
76132
76591
|
* Human-readable labels for each coder run step kind shown in prompt status lines.
|
|
76133
76592
|
*/
|
|
@@ -76172,23 +76631,6 @@ function formatPromptAttemptMetadata(status, attemptCount) {
|
|
|
76172
76631
|
return `(failed after ${attemptCount} attempts) `;
|
|
76173
76632
|
}
|
|
76174
76633
|
|
|
76175
|
-
/**
|
|
76176
|
-
* Formats runner details for prompt status lines.
|
|
76177
|
-
*/
|
|
76178
|
-
function formatRunnerSignature(runnerName, modelName, thinkingLevel) {
|
|
76179
|
-
const normalizedRunner = runnerName === null || runnerName === void 0 ? void 0 : runnerName.trim();
|
|
76180
|
-
const normalizedModel = modelName === null || modelName === void 0 ? void 0 : modelName.trim();
|
|
76181
|
-
const thinkingLevelSuffix = thinkingLevel ? ` thinking \`${thinkingLevel}\`` : '';
|
|
76182
|
-
if (!normalizedRunner && !normalizedModel) {
|
|
76183
|
-
return 'unknown';
|
|
76184
|
-
}
|
|
76185
|
-
const runnerLabel = normalizedRunner || 'unknown';
|
|
76186
|
-
if (!normalizedModel) {
|
|
76187
|
-
return `${runnerLabel}${thinkingLevelSuffix}`;
|
|
76188
|
-
}
|
|
76189
|
-
return `${runnerLabel} \`${normalizedModel}\`${thinkingLevelSuffix}`;
|
|
76190
|
-
}
|
|
76191
|
-
|
|
76192
76634
|
/**
|
|
76193
76635
|
* Replaces the complete todo status line while preserving its indentation.
|
|
76194
76636
|
*
|
|
@@ -79342,14 +79784,21 @@ async function verifyPrompts(options = DEFAULT_VERIFY_PROMPTS_OPTIONS) {
|
|
|
79342
79784
|
let promptFiles = initialFiles;
|
|
79343
79785
|
const skippedFiles = new Set();
|
|
79344
79786
|
while (true) {
|
|
79787
|
+
// Note: The git synchronization is applied around each single verification, not once per whole run
|
|
79788
|
+
await $pullCoderChanges({ gitSync: normalizedOptions.gitSync });
|
|
79789
|
+
if (normalizedOptions.gitSync.isAutoPullEnabled) {
|
|
79790
|
+
// Note: The pull can bring in prompt file changes, so the queue is reloaded before it is used
|
|
79791
|
+
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79792
|
+
}
|
|
79345
79793
|
displayPromptOverview(promptFiles);
|
|
79346
79794
|
// First priority: verify files where all prompts are marked as done
|
|
79347
79795
|
const fileWithAllDone = findFileWithAllDonePrompts(promptFiles, skippedFiles);
|
|
79348
79796
|
if (fileWithAllDone) {
|
|
79349
|
-
const
|
|
79350
|
-
if (wasSkipped) {
|
|
79797
|
+
const outcome = await verifyDonePromptsInFile(fileWithAllDone);
|
|
79798
|
+
if (outcome.wasSkipped) {
|
|
79351
79799
|
skippedFiles.add(fileWithAllDone.path);
|
|
79352
79800
|
}
|
|
79801
|
+
await $commitVerificationOutcome(normalizedOptions.gitSync, outcome);
|
|
79353
79802
|
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79354
79803
|
continue;
|
|
79355
79804
|
}
|
|
@@ -79359,10 +79808,20 @@ async function verifyPrompts(options = DEFAULT_VERIFY_PROMPTS_OPTIONS) {
|
|
|
79359
79808
|
console.info(colors.green('\n✅ All prompts have been verified.'));
|
|
79360
79809
|
break;
|
|
79361
79810
|
}
|
|
79362
|
-
await resolvePrompt(nextPrompt);
|
|
79811
|
+
const outcome = await resolvePrompt(nextPrompt);
|
|
79812
|
+
await $commitVerificationOutcome(normalizedOptions.gitSync, outcome);
|
|
79363
79813
|
promptFiles = (await loadPromptFilesForVerification(normalizedOptions)).promptFiles;
|
|
79364
79814
|
}
|
|
79365
79815
|
}
|
|
79816
|
+
/**
|
|
79817
|
+
* Commits and pushes one applied verification when the git synchronization is enabled.
|
|
79818
|
+
*/
|
|
79819
|
+
async function $commitVerificationOutcome(gitSync, outcome) {
|
|
79820
|
+
if (outcome.commitMessage === null) {
|
|
79821
|
+
return;
|
|
79822
|
+
}
|
|
79823
|
+
await $commitCoderChanges({ gitSync, commitMessage: outcome.commitMessage });
|
|
79824
|
+
}
|
|
79366
79825
|
/**
|
|
79367
79826
|
* Parses supported command-line arguments for the standalone verification script.
|
|
79368
79827
|
*/
|
|
@@ -79370,6 +79829,11 @@ function parseVerifyPromptsCliOptions(args) {
|
|
|
79370
79829
|
return {
|
|
79371
79830
|
reverse: args.includes('--reverse'),
|
|
79372
79831
|
ignore: readRepeatableStringOption(args, '--ignore'),
|
|
79832
|
+
gitSync: {
|
|
79833
|
+
isCommitEnabled: args.includes('--commit'),
|
|
79834
|
+
isAutoPushEnabled: args.includes('--auto-push'),
|
|
79835
|
+
isAutoPullEnabled: args.includes('--auto-pull'),
|
|
79836
|
+
},
|
|
79373
79837
|
};
|
|
79374
79838
|
}
|
|
79375
79839
|
/**
|
|
@@ -79421,10 +79885,11 @@ async function prepareArchiveDirectory() {
|
|
|
79421
79885
|
* Normalizes verification options so the rest of the flow can assume stable defaults.
|
|
79422
79886
|
*/
|
|
79423
79887
|
function normalizeVerifyPromptsOptions(options) {
|
|
79424
|
-
var _a, _b;
|
|
79888
|
+
var _a, _b, _c;
|
|
79425
79889
|
return {
|
|
79426
79890
|
reverse: (_a = options.reverse) !== null && _a !== void 0 ? _a : false,
|
|
79427
79891
|
ignore: normalizeIgnoreValues((_b = options.ignore) !== null && _b !== void 0 ? _b : []),
|
|
79892
|
+
gitSync: (_c = options.gitSync) !== null && _c !== void 0 ? _c : DISABLED_CODER_GIT_SYNC_OPTIONS,
|
|
79428
79893
|
};
|
|
79429
79894
|
}
|
|
79430
79895
|
/**
|
|
@@ -79555,7 +80020,6 @@ function findFileWithAllDonePrompts(promptFiles, skippedFiles) {
|
|
|
79555
80020
|
/**
|
|
79556
80021
|
* Verifies the last done [x] prompt in a file and decides whether to archive it or add a repair prompt.
|
|
79557
80022
|
* Ignores not-ready prompts like [-], [.], [?], etc.
|
|
79558
|
-
* Returns true if the file was skipped, false otherwise.
|
|
79559
80023
|
*/
|
|
79560
80024
|
async function verifyDonePromptsInFile(file) {
|
|
79561
80025
|
const doneCount = file.sections.filter((s) => s.status === 'done').length;
|
|
@@ -79575,31 +80039,44 @@ async function verifyDonePromptsInFile(file) {
|
|
|
79575
80039
|
}
|
|
79576
80040
|
if (!lastDoneSection) {
|
|
79577
80041
|
console.info(colors.gray('No done [x] prompts found in this file.'));
|
|
79578
|
-
return false;
|
|
80042
|
+
return { wasSkipped: false, commitMessage: null };
|
|
79579
80043
|
}
|
|
79580
80044
|
console.info(colors.gray('Verifying the last [x] prompt in the file...\n'));
|
|
79581
80045
|
displayPromptSnippet({ file, section: lastDoneSection });
|
|
79582
80046
|
const decision = await promptForDoneVerification(file, lastDoneSection);
|
|
79583
80047
|
if (decision === 'done') {
|
|
79584
80048
|
await archivePromptFile(file);
|
|
79585
|
-
return false;
|
|
80049
|
+
return { wasSkipped: false, commitMessage: buildArchiveCommitMessage(file) };
|
|
79586
80050
|
}
|
|
79587
80051
|
else if (decision === 'needs-work') {
|
|
79588
80052
|
console.info(colors.yellow('\n⚠️ This prompt needs repair.'));
|
|
79589
80053
|
await appendRepairPrompt(file, lastDoneSection);
|
|
79590
|
-
return false;
|
|
80054
|
+
return { wasSkipped: false, commitMessage: buildRepairCommitMessage(file) };
|
|
79591
80055
|
}
|
|
79592
80056
|
else {
|
|
79593
80057
|
console.info(colors.gray('\n⏩ Skipped, no changes made.'));
|
|
79594
|
-
return true;
|
|
80058
|
+
return { wasSkipped: true, commitMessage: null };
|
|
79595
80059
|
}
|
|
79596
80060
|
}
|
|
80061
|
+
/**
|
|
80062
|
+
* Builds the commit message describing one archived prompt file.
|
|
80063
|
+
*/
|
|
80064
|
+
function buildArchiveCommitMessage(file) {
|
|
80065
|
+
return `✅ Prompt done and archived \`${file.name}\``; // <- $commitCoderChanges({
|
|
80066
|
+
}
|
|
80067
|
+
/**
|
|
80068
|
+
* Builds the commit message describing one appended repair prompt.
|
|
80069
|
+
*/
|
|
80070
|
+
function buildRepairCommitMessage(file) {
|
|
80071
|
+
return `❌ Repair prompt added into \`${file.name}\``; // <- $commitCoderChanges({
|
|
80072
|
+
}
|
|
79597
80073
|
/**
|
|
79598
80074
|
* Asks the user to verify if a done prompt is actually completed.
|
|
79599
80075
|
* Returns 'done' if verified, 'needs-work' if not done, or 'skip' to skip this file.
|
|
79600
80076
|
*/
|
|
79601
80077
|
async function promptForDoneVerification(file, section) {
|
|
79602
80078
|
const promptLabel = buildPromptLabelForDisplay(file, section);
|
|
80079
|
+
const { default: prompts } = await loadPromptsModule();
|
|
79603
80080
|
const response = await prompts({
|
|
79604
80081
|
type: 'select',
|
|
79605
80082
|
name: 'verified',
|
|
@@ -79668,16 +80145,17 @@ async function resolvePrompt(selection) {
|
|
|
79668
80145
|
const decision = await promptForDecision(selection);
|
|
79669
80146
|
if (decision === 'done') {
|
|
79670
80147
|
await archivePromptFile(selection.file);
|
|
80148
|
+
return { wasSkipped: false, commitMessage: buildArchiveCommitMessage(selection.file) };
|
|
79671
80149
|
}
|
|
79672
|
-
|
|
79673
|
-
|
|
79674
|
-
}
|
|
80150
|
+
await appendRepairPrompt(selection.file, selection.section);
|
|
80151
|
+
return { wasSkipped: false, commitMessage: buildRepairCommitMessage(selection.file) };
|
|
79675
80152
|
}
|
|
79676
80153
|
/**
|
|
79677
80154
|
* Presents the interactive decision menu for the current prompt section.
|
|
79678
80155
|
*/
|
|
79679
80156
|
async function promptForDecision(selection) {
|
|
79680
80157
|
const promptLabel = buildPromptLabelForDisplay(selection.file, selection.section);
|
|
80158
|
+
const { default: prompts } = await loadPromptsModule();
|
|
79681
80159
|
const response = await prompts({
|
|
79682
80160
|
type: 'select',
|
|
79683
80161
|
name: 'decision',
|