@promptbook/cli 0.112.0-121 → 0.112.0-124
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -14
- package/agents/default/developer.book +23 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/user-chats/[chatId]/messages/route.ts +4 -11
- package/apps/agents-server/src/app/api/scrape/route.ts +18 -0
- package/apps/agents-server/src/tools/createAgentProgressTools.ts +6 -4
- package/apps/agents-server/src/utils/assertSafeUrl.ts +136 -0
- package/apps/agents-server/src/utils/authenticateUser.ts +2 -1
- package/apps/agents-server/src/utils/getCurrentUser.ts +2 -1
- package/apps/agents-server/src/utils/isAdminPasswordEqual.ts +28 -0
- package/apps/agents-server/src/utils/isUserGlobalAdmin.ts +3 -1
- package/apps/agents-server/src/utils/userChat/createRunUserChatJobPersistenceController.ts +21 -0
- package/apps/agents-server/src/utils/userChat/retryUserChatJob.ts +4 -0
- package/apps/agents-server/src/utils/userChat/userChatMessageLifecycle.ts +2 -0
- package/apps/agents-server/src/utils/userChat/userChatProgressCard.ts +288 -0
- package/esm/index.es.js +1430 -283
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +6 -0
- package/esm/scripts/run-codex-prompts/main/findUnwrittenPrompts.d.ts +19 -0
- package/esm/scripts/run-codex-prompts/main/runCodexPromptsServer.d.ts +27 -0
- package/esm/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -1
- package/esm/scripts/run-codex-prompts/server/coderServerHtml.d.ts +9 -0
- package/esm/scripts/run-codex-prompts/server/runCoderHttpServer.d.ts +23 -0
- package/esm/scripts/run-codex-prompts/server/updatePromptSection.d.ts +9 -0
- package/esm/src/cli/cli-commands/coder/ensureCoderDeveloperAgentFile.d.ts +25 -0
- package/esm/src/cli/cli-commands/coder/find-unwritten.d.ts +10 -0
- package/esm/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.d.ts +2 -0
- package/esm/src/cli/cli-commands/coder/server.d.ts +13 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/cli/cli-commands/coder/ensureCoderDeveloperAgentFile.ts +79 -0
- package/src/cli/cli-commands/coder/find-unwritten.ts +58 -0
- package/src/cli/cli-commands/coder/getDefaultCoderPackageJsonScripts.ts +1 -1
- package/src/cli/cli-commands/coder/init.ts +6 -1
- package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +10 -0
- package/src/cli/cli-commands/coder/printInitializationSummary.ts +3 -0
- package/src/cli/cli-commands/coder/run.ts +26 -11
- package/src/cli/cli-commands/coder/server.ts +239 -0
- package/src/cli/cli-commands/coder.ts +6 -0
- package/src/other/templates/getTemplatesPipelineCollection.ts +727 -1105
- package/src/version.ts +2 -2
- package/src/versions.txt +3 -1
- package/umd/index.umd.js +1431 -284
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/common/resolveAgentSystemMessage.d.ts +6 -0
- package/umd/scripts/run-codex-prompts/main/findUnwrittenPrompts.d.ts +19 -0
- package/umd/scripts/run-codex-prompts/main/runCodexPromptsServer.d.ts +27 -0
- package/umd/scripts/run-codex-prompts/main/runPromptRound.d.ts +2 -1
- package/umd/scripts/run-codex-prompts/server/coderServerHtml.d.ts +9 -0
- package/umd/scripts/run-codex-prompts/server/runCoderHttpServer.d.ts +23 -0
- package/umd/scripts/run-codex-prompts/server/updatePromptSection.d.ts +9 -0
- package/umd/src/cli/cli-commands/coder/ensureCoderDeveloperAgentFile.d.ts +25 -0
- package/umd/src/cli/cli-commands/coder/find-unwritten.d.ts +10 -0
- package/umd/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.d.ts +2 -0
- package/umd/src/cli/cli-commands/coder/server.d.ts +13 -0
- package/umd/src/version.d.ts +1 -1
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import colors from 'colors';
|
|
2
|
+
import { Command as Program /* <- Note: [🔸] Using Program because Command is misleading name */ } from 'commander';
|
|
3
|
+
import { Option } from 'commander';
|
|
4
|
+
import { spaceTrim } from 'spacetrim';
|
|
5
|
+
import { NETWORK_LIMITS } from '../../../constants';
|
|
6
|
+
import { assertsError } from '../../../errors/assertsError';
|
|
7
|
+
import { NotAllowed } from '../../../errors/NotAllowed';
|
|
8
|
+
import type { number_port } from '../../../types/number_positive';
|
|
9
|
+
import type { $side_effect } from '../../../utils/organization/$side_effect';
|
|
10
|
+
import { handleActionErrors } from '../common/handleActionErrors';
|
|
11
|
+
import type { PromptRunnerCliOptions } from '../common/promptRunnerCliOptions';
|
|
12
|
+
import {
|
|
13
|
+
addPromptRunnerExecutionOptions,
|
|
14
|
+
addPromptRunnerSelectionOptions,
|
|
15
|
+
normalizePromptRunnerCliOptions,
|
|
16
|
+
PROMPT_RUNNER_DESCRIPTION,
|
|
17
|
+
} from '../common/promptRunnerCliOptions';
|
|
18
|
+
import { parseDuration } from '../../../../scripts/run-codex-prompts/common/parseDuration';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Default port used by `ptbk coder server`.
|
|
22
|
+
*
|
|
23
|
+
* @private internal constant of `ptbk coder server`
|
|
24
|
+
*/
|
|
25
|
+
const DEFAULT_CODER_SERVER_PORT = '4441';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Initializes `coder server` command for Promptbook CLI utilities.
|
|
29
|
+
*
|
|
30
|
+
* Runs the same prompt processing logic as `ptbk coder run` but keeps the process alive
|
|
31
|
+
* and serves a kanban web UI on the configured port.
|
|
32
|
+
*
|
|
33
|
+
* Note: `$` is used to indicate that this function is not a pure function - it registers a command in the CLI
|
|
34
|
+
*
|
|
35
|
+
* @private internal function of `promptbookCli`
|
|
36
|
+
*/
|
|
37
|
+
export function $initializeCoderServerCommand(program: Program): $side_effect {
|
|
38
|
+
const command = program.command('server');
|
|
39
|
+
command.description(
|
|
40
|
+
spaceTrim(`
|
|
41
|
+
Start a coder server that watches for prompts and serves a kanban web UI
|
|
42
|
+
|
|
43
|
+
${PROMPT_RUNNER_DESCRIPTION}
|
|
44
|
+
|
|
45
|
+
Features:
|
|
46
|
+
- Runs the same prompt processing as \`ptbk coder run\`
|
|
47
|
+
- Does not exit when all prompts are done; polls for new prompt files instead
|
|
48
|
+
- Serves a kanban board at http://localhost:<port> for visual progress tracking
|
|
49
|
+
- Allows editing prompt files directly from the browser (Trello-style)
|
|
50
|
+
- Play / pause button in the browser stays in sync with the CLI pause state
|
|
51
|
+
- Press "p" in the terminal to pause / resume (same as \`ptbk coder run\`)
|
|
52
|
+
`),
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
command.addOption(
|
|
56
|
+
new Option('--port <port>', 'Port to start the coder server on')
|
|
57
|
+
.env('PTBK_CODER_SERVER_PORT')
|
|
58
|
+
.default(DEFAULT_CODER_SERVER_PORT),
|
|
59
|
+
);
|
|
60
|
+
command.option('--dry-run', 'Print unwritten prompts without executing', false);
|
|
61
|
+
addPromptRunnerSelectionOptions(command);
|
|
62
|
+
command.option(
|
|
63
|
+
'--agent <agent-book-path>',
|
|
64
|
+
'Path to a .book file whose compiled system message is prepended to each coding prompt',
|
|
65
|
+
);
|
|
66
|
+
command.option(
|
|
67
|
+
'--context <context-or-file>',
|
|
68
|
+
'Append extra instructions either inline or from a file path relative to the current project',
|
|
69
|
+
);
|
|
70
|
+
command.option(
|
|
71
|
+
'--test <test-command...>',
|
|
72
|
+
'Run a verification command after each prompt; quote it when the command itself contains top-level flags',
|
|
73
|
+
);
|
|
74
|
+
command.option(
|
|
75
|
+
'--preserve-logs',
|
|
76
|
+
'Keep generated temp prompt/log artifacts after successful rounds for debugging and analytics',
|
|
77
|
+
false,
|
|
78
|
+
);
|
|
79
|
+
addPromptRunnerExecutionOptions(command);
|
|
80
|
+
command.option('--priority <minimum-priority>', 'Filter prompts by minimum priority level', parseIntOption, 0);
|
|
81
|
+
command.option(
|
|
82
|
+
'--wait [duration]',
|
|
83
|
+
spaceTrim(`
|
|
84
|
+
Wait between prompt rounds.
|
|
85
|
+
Without a value (default): waits for user confirmation before each prompt (interactive mode).
|
|
86
|
+
With a duration like 1h, 30m, 5s: waits that long between prompts to avoid hitting rate limits of the harness.
|
|
87
|
+
`),
|
|
88
|
+
true,
|
|
89
|
+
);
|
|
90
|
+
command.option('--no-wait', 'Skip all waiting between prompts and run non-interactively');
|
|
91
|
+
command.option(
|
|
92
|
+
'--auto-migrate',
|
|
93
|
+
'Run testing-server database migrations automatically after each successfully processed prompt',
|
|
94
|
+
);
|
|
95
|
+
command.option(
|
|
96
|
+
'--allow-destructive-auto-migrate',
|
|
97
|
+
'Allow auto-migrate even when heuristic SQL safety check flags destructive pending migrations',
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
command.action(
|
|
101
|
+
handleActionErrors(async (cliOptions) => {
|
|
102
|
+
const {
|
|
103
|
+
port: rawPort,
|
|
104
|
+
dryRun,
|
|
105
|
+
agent,
|
|
106
|
+
context,
|
|
107
|
+
test,
|
|
108
|
+
preserveLogs,
|
|
109
|
+
priority,
|
|
110
|
+
wait,
|
|
111
|
+
autoMigrate,
|
|
112
|
+
allowDestructiveAutoMigrate,
|
|
113
|
+
} = cliOptions as {
|
|
114
|
+
readonly port: string;
|
|
115
|
+
readonly dryRun: boolean;
|
|
116
|
+
readonly agent?: string;
|
|
117
|
+
readonly context?: string;
|
|
118
|
+
readonly test?: string | string[];
|
|
119
|
+
readonly preserveLogs: boolean;
|
|
120
|
+
readonly priority: number;
|
|
121
|
+
readonly wait: boolean | string;
|
|
122
|
+
readonly autoMigrate: boolean;
|
|
123
|
+
readonly allowDestructiveAutoMigrate: boolean;
|
|
124
|
+
} & PromptRunnerCliOptions;
|
|
125
|
+
|
|
126
|
+
const port = parseCoderServerPort(rawPort);
|
|
127
|
+
const testCommand = normalizeCommandOptionValue(test);
|
|
128
|
+
const runnerOptions = normalizePromptRunnerCliOptions(cliOptions as PromptRunnerCliOptions, {
|
|
129
|
+
isAgentRequired: !dryRun,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// [1] Parse the --wait option (same logic as `coder run`)
|
|
133
|
+
let waitForUser = false;
|
|
134
|
+
let waitBetweenPrompts = 0;
|
|
135
|
+
|
|
136
|
+
if (wait === true) {
|
|
137
|
+
waitForUser = true;
|
|
138
|
+
} else if (typeof wait === 'string' && wait !== '') {
|
|
139
|
+
waitBetweenPrompts = parseDuration(wait);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const runOptions = {
|
|
143
|
+
port,
|
|
144
|
+
dryRun,
|
|
145
|
+
waitForUser,
|
|
146
|
+
waitBetweenPrompts,
|
|
147
|
+
noCommit: runnerOptions.noCommit,
|
|
148
|
+
ignoreGitChanges: runnerOptions.ignoreGitChanges,
|
|
149
|
+
agentName: runnerOptions.agentName,
|
|
150
|
+
model: runnerOptions.model,
|
|
151
|
+
agent,
|
|
152
|
+
context,
|
|
153
|
+
testCommand,
|
|
154
|
+
preserveLogs,
|
|
155
|
+
noUi: runnerOptions.noUi,
|
|
156
|
+
thinkingLevel: runnerOptions.thinkingLevel,
|
|
157
|
+
priority,
|
|
158
|
+
normalizeLineEndings: runnerOptions.normalizeLineEndings,
|
|
159
|
+
allowCredits: runnerOptions.allowCredits,
|
|
160
|
+
autoMigrate,
|
|
161
|
+
allowDestructiveAutoMigrate,
|
|
162
|
+
autoPush: runnerOptions.autoPush,
|
|
163
|
+
autoPull: runnerOptions.autoPull,
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// Note: Import dynamically to avoid loading heavy dependencies until needed
|
|
167
|
+
const { runCodexPromptsServer } = await import(
|
|
168
|
+
'../../../../scripts/run-codex-prompts/main/runCodexPromptsServer'
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
await runCodexPromptsServer(runOptions);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
assertsError(error);
|
|
175
|
+
console.error(colors.bgRed(`${error.name}`));
|
|
176
|
+
console.error(colors.red(error.stack || error.message));
|
|
177
|
+
return process.exit(1);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return process.exit(0);
|
|
181
|
+
}),
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Parses and validates the coder server port number.
|
|
187
|
+
*
|
|
188
|
+
* @private internal utility of `coder server` command
|
|
189
|
+
*/
|
|
190
|
+
function parseCoderServerPort(rawPort: string): number_port {
|
|
191
|
+
const port = Number.parseInt(rawPort, 10);
|
|
192
|
+
|
|
193
|
+
if (!Number.isInteger(port) || port <= 0 || port > NETWORK_LIMITS.MAX_PORT) {
|
|
194
|
+
throw new NotAllowed(
|
|
195
|
+
spaceTrim(`
|
|
196
|
+
Invalid coder server port: \`${rawPort}\`.
|
|
197
|
+
|
|
198
|
+
Use \`--port\` or \`PTBK_CODER_SERVER_PORT\` with an integer between \`1\` and \`${NETWORK_LIMITS.MAX_PORT}\`.
|
|
199
|
+
`),
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return port as number_port;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Parses an integer option value.
|
|
208
|
+
*
|
|
209
|
+
* @private internal utility of `coder server` command
|
|
210
|
+
*/
|
|
211
|
+
function parseIntOption(value: string): number {
|
|
212
|
+
const parsed = parseInt(value, 10);
|
|
213
|
+
if (isNaN(parsed)) {
|
|
214
|
+
throw new Error(`Invalid number: ${value}`);
|
|
215
|
+
}
|
|
216
|
+
return parsed;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Joins one Commander option that may be parsed either as a single string or a variadic token array.
|
|
221
|
+
*
|
|
222
|
+
* @private internal utility of `coder server` command
|
|
223
|
+
*/
|
|
224
|
+
function normalizeCommandOptionValue(value: string | string[] | undefined): string | undefined {
|
|
225
|
+
if (value === undefined) {
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const parts = Array.isArray(value) ? value : [value];
|
|
230
|
+
const normalizedValue = parts
|
|
231
|
+
.map((part) => part.trim())
|
|
232
|
+
.filter(Boolean)
|
|
233
|
+
.join(' ')
|
|
234
|
+
.trim();
|
|
235
|
+
return normalizedValue === '' ? undefined : normalizedValue;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Note: [🟡] Code for CLI command [server](src/cli/cli-commands/coder/server.ts) should never be published outside of `@promptbook/cli`
|
|
239
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -6,9 +6,11 @@ import { spaceTrim } from 'spacetrim';
|
|
|
6
6
|
import type { $side_effect } from '../../utils/organization/$side_effect';
|
|
7
7
|
import { $initializeCoderFindFreshEmojiTagCommand } from './coder/find-fresh-emoji-tags';
|
|
8
8
|
import { $initializeCoderFindRefactorCandidatesCommand } from './coder/find-refactor-candidates';
|
|
9
|
+
import { $initializeCoderFindUnwrittenCommand } from './coder/find-unwritten';
|
|
9
10
|
import { $initializeCoderGenerateBoilerplatesCommand } from './coder/generate-boilerplates';
|
|
10
11
|
import { $initializeCoderInitCommand } from './coder/init';
|
|
11
12
|
import { $initializeCoderRunCommand } from './coder/run';
|
|
13
|
+
import { $initializeCoderServerCommand } from './coder/server';
|
|
12
14
|
import { $initializeCoderVerifyCommand } from './coder/verify';
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -36,7 +38,9 @@ export function $initializeCoderCommand(program: Program): $side_effect {
|
|
|
36
38
|
- init: Initialize coder configuration in current project
|
|
37
39
|
- generate-boilerplates: Generate prompt boilerplate files
|
|
38
40
|
- find-refactor-candidates: Find files that need refactoring
|
|
41
|
+
- find-unwritten: List prompt sections that still need to be authored
|
|
39
42
|
- run: Run coding prompts with AI agents
|
|
43
|
+
- server: Start a long-running coder server with a kanban web UI
|
|
40
44
|
- verify: Verify completed prompts
|
|
41
45
|
- find-fresh-emoji-tags: Find unused emoji tags
|
|
42
46
|
`),
|
|
@@ -46,7 +50,9 @@ export function $initializeCoderCommand(program: Program): $side_effect {
|
|
|
46
50
|
$initializeCoderInitCommand(coderCommand);
|
|
47
51
|
$initializeCoderGenerateBoilerplatesCommand(coderCommand);
|
|
48
52
|
$initializeCoderFindRefactorCandidatesCommand(coderCommand);
|
|
53
|
+
$initializeCoderFindUnwrittenCommand(coderCommand);
|
|
49
54
|
$initializeCoderRunCommand(coderCommand);
|
|
55
|
+
$initializeCoderServerCommand(coderCommand);
|
|
50
56
|
$initializeCoderVerifyCommand(coderCommand);
|
|
51
57
|
$initializeCoderFindFreshEmojiTagCommand(coderCommand);
|
|
52
58
|
|