@promptbook/cli 0.114.0-49 → 0.114.0-50
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 +3 -3
- package/apps/agents-server/src/app/globals.css +15 -0
- package/apps/agents-server/src/components/ContextMenu/ContextMenuPanel.tsx +1 -11
- package/apps/agents-server/src/utils/applicationFonts.ts +4 -25
- package/esm/index.es.js +36124 -33191
- package/esm/index.es.js.map +1 -1
- package/esm/scripts/run-codex-prompts/checks/CoderCheckExecutionError.d.ts +6 -0
- package/esm/scripts/run-codex-prompts/checks/CoderCheckFailedError.d.ts +6 -0
- package/esm/scripts/run-codex-prompts/checks/buildCheckBeforeScriptPath.d.ts +2 -0
- package/esm/scripts/run-codex-prompts/checks/createCheckBeforeRepairPrompt.d.ts +3 -1
- package/esm/scripts/run-codex-prompts/checks/runCheckBefore.d.ts +5 -0
- package/esm/scripts/run-codex-prompts/checks/runCoderCheck.d.ts +17 -0
- package/esm/scripts/run-codex-prompts/checks/runCoderCheckRepair.d.ts +40 -0
- package/esm/scripts/run-codex-prompts/checks/runPromptWithCheckFeedback.d.ts +5 -0
- package/esm/scripts/run-codex-prompts/common/createFreeDiskSpaceGuard.d.ts +3 -0
- package/esm/scripts/run-codex-prompts/common/resolveCoderProjectContext.d.ts +2 -0
- package/esm/scripts/run-codex-prompts/common/runGoScript/$spawnLoggedBashScript.d.ts +2 -0
- package/esm/scripts/run-codex-prompts/common/runGoScript/buildCoderExecutionArtifactPaths.d.ts +2 -0
- package/esm/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/common/sleepWithCountdown.d.ts +2 -0
- package/esm/scripts/run-codex-prompts/common/waitForSkippableWorldTimeDeadline.d.ts +1 -0
- package/esm/scripts/run-codex-prompts/common/withCoderWorkspaceLock.d.ts +9 -0
- package/esm/scripts/run-codex-prompts/git/CoderGitOperationError.d.ts +9 -0
- package/esm/scripts/run-codex-prompts/git/CoderPhasePersistence.d.ts +105 -0
- package/esm/scripts/run-codex-prompts/git/CoderPhaseRecovery.d.ts +43 -0
- package/esm/scripts/run-codex-prompts/git/buildCoderCheckCommitMessage.d.ts +11 -0
- package/esm/scripts/run-codex-prompts/git/coderCommitScope.d.ts +14 -1
- package/esm/scripts/run-codex-prompts/git/coderFinalizationFiles.d.ts +14 -0
- package/esm/scripts/run-codex-prompts/git/coderIndexLease.d.ts +11 -0
- package/esm/scripts/run-codex-prompts/git/coderRepositoryFiles.d.ts +6 -0
- package/esm/scripts/run-codex-prompts/git/coderRepositorySnapshot.d.ts +62 -0
- package/esm/scripts/run-codex-prompts/git/coderRepositoryView.d.ts +30 -0
- package/esm/scripts/run-codex-prompts/git/commitChanges.d.ts +36 -3
- package/esm/scripts/run-codex-prompts/git/gitLongPathsSupport.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/git/pullLatestChanges.d.ts +3 -1
- package/esm/scripts/run-codex-prompts/git/quoteGitArgument.d.ts +5 -0
- package/esm/scripts/run-codex-prompts/git/runGitCommand.d.ts +4 -0
- package/esm/scripts/run-codex-prompts/git/runWorkspaceGitWithIndexReadRetry.d.ts +7 -0
- package/esm/scripts/run-codex-prompts/git/workingTreeChanges.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/isolation/coderIsolationArtifacts.d.ts +16 -0
- package/esm/scripts/run-codex-prompts/isolation/coderIsolationIgnoredFiles.d.ts +18 -0
- package/esm/scripts/run-codex-prompts/isolation/createCoderIsolationWorktree.d.ts +1 -2
- package/esm/scripts/run-codex-prompts/isolation/mergeCoderIsolationWorktree.d.ts +5 -5
- package/esm/scripts/run-codex-prompts/isolation/preserveCoderIsolationRecovery.d.ts +3 -0
- package/esm/scripts/run-codex-prompts/isolation/runIsolatedPromptRound.d.ts +2 -2
- package/esm/scripts/run-codex-prompts/main/prepareCoderPromptExecution.d.ts +18 -0
- package/esm/scripts/run-codex-prompts/main/runCoderFix.d.ts +24 -0
- package/esm/scripts/run-codex-prompts/main/runPromptRound.d.ts +12 -2
- package/esm/scripts/run-codex-prompts/prompts/buildPromptRunTraceContent.d.ts +5 -2
- package/esm/scripts/run-codex-prompts/prompts/refreshPromptSelection.d.ts +6 -0
- package/esm/scripts/run-codex-prompts/prompts/writePromptErrorLog.d.ts +4 -0
- package/esm/scripts/run-codex-prompts/prompts/writePromptFile.d.ts +2 -0
- package/esm/scripts/run-codex-prompts/prompts/writePromptRunTrace.d.ts +2 -0
- package/esm/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/ui/buildCoderCheckRepairUiFrame.d.ts +3 -0
- package/esm/scripts/run-codex-prompts/ui/output/CoderOutputEvent.d.ts +1 -1
- package/esm/scripts/run-codex-prompts/ui/output/CoderRunOutput.d.ts +2 -2
- package/esm/scripts/run-codex-prompts/ui/renderCoderRunUi.d.ts +4 -0
- package/esm/src/cli/cli-commands/coder/add.d.ts +7 -2
- package/esm/src/cli/cli-commands/coder/ensureCoderGitattributesFile.d.ts +13 -0
- package/esm/src/cli/cli-commands/coder/ensureCoderGitignoreFile.d.ts +1 -1
- package/esm/src/cli/cli-commands/coder/fix.d.ts +7 -0
- package/esm/src/cli/cli-commands/coder/fix.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/coder/fixWorkflow.test.d.ts +1 -0
- package/esm/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.d.ts +1 -0
- package/esm/src/cli/cli-commands/coder.d.ts +1 -0
- package/esm/src/cli/cli-commands/common/coderCheckCliOptions.d.ts +1 -1
- package/esm/src/cli/cli-commands/common/ensureProjectTextFile.d.ts +7 -0
- package/esm/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.d.ts +3 -1
- package/esm/src/cli/cli-commands/common/validateCoderRunOptions.d.ts +1 -1
- package/esm/src/cli/cli-commands/common/workspaceRepository.d.ts +12 -0
- package/esm/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/cli/cli-commands/coder/add.ts +20 -3
- package/src/cli/cli-commands/coder/ensureCoderGitattributesFile.ts +25 -0
- package/src/cli/cli-commands/coder/ensureCoderGitignoreFile.ts +3 -3
- package/src/cli/cli-commands/coder/ensureCoderMarkdownFile.ts +2 -20
- package/src/cli/cli-commands/coder/fix.ts +166 -0
- package/src/cli/cli-commands/coder/fixtures/fix.cjs +29 -0
- package/src/cli/cli-commands/coder/fixtures/healthyDisk.cjs +4 -0
- package/src/cli/cli-commands/coder/getCoderInitializationCommitPaths.ts +2 -0
- package/src/cli/cli-commands/coder/init.ts +3 -1
- package/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.ts +7 -0
- package/src/cli/cli-commands/coder/planning/fixtures/coding.cjs +4 -0
- package/src/cli/cli-commands/coder/printInitializationSummary.ts +2 -0
- package/src/cli/cli-commands/coder/promptsReadmeTemplate.ts +25 -1
- package/src/cli/cli-commands/coder/run.ts +17 -8
- package/src/cli/cli-commands/coder/server.ts +9 -6
- package/src/cli/cli-commands/coder.ts +4 -0
- package/src/cli/cli-commands/common/coderCheckCliOptions.ts +7 -6
- package/src/cli/cli-commands/common/ensureProjectTextFile.ts +35 -0
- package/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.ts +13 -0
- package/src/cli/cli-commands/common/validateCoderRunOptions.ts +16 -1
- package/src/cli/cli-commands/common/workspaceRepository.ts +61 -13
- package/src/other/templates/getTemplatesPipelineCollection.ts +1825 -1089
- package/src/utils/execCommand/$execCommand.ts +2 -1
- package/src/version.ts +2 -2
- package/src/versions.txt +1 -0
- package/umd/index.umd.js +36204 -33273
- package/umd/index.umd.js.map +1 -1
- package/umd/scripts/run-codex-prompts/checks/CoderCheckExecutionError.d.ts +6 -0
- package/umd/scripts/run-codex-prompts/checks/CoderCheckFailedError.d.ts +6 -0
- package/umd/scripts/run-codex-prompts/checks/buildCheckBeforeScriptPath.d.ts +2 -0
- package/umd/scripts/run-codex-prompts/checks/createCheckBeforeRepairPrompt.d.ts +3 -1
- package/umd/scripts/run-codex-prompts/checks/runCheckBefore.d.ts +5 -0
- package/umd/scripts/run-codex-prompts/checks/runCoderCheck.d.ts +17 -0
- package/umd/scripts/run-codex-prompts/checks/runCoderCheckRepair.d.ts +40 -0
- package/umd/scripts/run-codex-prompts/checks/runPromptWithCheckFeedback.d.ts +5 -0
- package/umd/scripts/run-codex-prompts/common/createFreeDiskSpaceGuard.d.ts +3 -0
- package/umd/scripts/run-codex-prompts/common/resolveCoderProjectContext.d.ts +2 -0
- package/umd/scripts/run-codex-prompts/common/runGoScript/$spawnLoggedBashScript.d.ts +2 -0
- package/umd/scripts/run-codex-prompts/common/runGoScript/buildCoderExecutionArtifactPaths.d.ts +2 -0
- package/umd/scripts/run-codex-prompts/common/runGoScript/scriptExecutionLog.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/common/sleepWithCountdown.d.ts +2 -0
- package/umd/scripts/run-codex-prompts/common/waitForSkippableWorldTimeDeadline.d.ts +1 -0
- package/umd/scripts/run-codex-prompts/common/withCoderWorkspaceLock.d.ts +9 -0
- package/umd/scripts/run-codex-prompts/git/CoderGitOperationError.d.ts +9 -0
- package/umd/scripts/run-codex-prompts/git/CoderPhasePersistence.d.ts +105 -0
- package/umd/scripts/run-codex-prompts/git/CoderPhaseRecovery.d.ts +43 -0
- package/umd/scripts/run-codex-prompts/git/buildCoderCheckCommitMessage.d.ts +11 -0
- package/umd/scripts/run-codex-prompts/git/coderCommitScope.d.ts +14 -1
- package/umd/scripts/run-codex-prompts/git/coderFinalizationFiles.d.ts +14 -0
- package/umd/scripts/run-codex-prompts/git/coderIndexLease.d.ts +11 -0
- package/umd/scripts/run-codex-prompts/git/coderRepositoryFiles.d.ts +6 -0
- package/umd/scripts/run-codex-prompts/git/coderRepositorySnapshot.d.ts +62 -0
- package/umd/scripts/run-codex-prompts/git/coderRepositoryView.d.ts +30 -0
- package/umd/scripts/run-codex-prompts/git/commitChanges.d.ts +36 -3
- package/umd/scripts/run-codex-prompts/git/gitLongPathsSupport.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/git/pullLatestChanges.d.ts +3 -1
- package/umd/scripts/run-codex-prompts/git/quoteGitArgument.d.ts +5 -0
- package/umd/scripts/run-codex-prompts/git/runGitCommand.d.ts +4 -0
- package/umd/scripts/run-codex-prompts/git/runWorkspaceGitWithIndexReadRetry.d.ts +7 -0
- package/umd/scripts/run-codex-prompts/git/workingTreeChanges.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/isolation/coderIsolationArtifacts.d.ts +16 -0
- package/umd/scripts/run-codex-prompts/isolation/coderIsolationIgnoredFiles.d.ts +18 -0
- package/umd/scripts/run-codex-prompts/isolation/createCoderIsolationWorktree.d.ts +1 -2
- package/umd/scripts/run-codex-prompts/isolation/mergeCoderIsolationWorktree.d.ts +5 -5
- package/umd/scripts/run-codex-prompts/isolation/preserveCoderIsolationRecovery.d.ts +3 -0
- package/umd/scripts/run-codex-prompts/isolation/runIsolatedPromptRound.d.ts +2 -2
- package/umd/scripts/run-codex-prompts/main/prepareCoderPromptExecution.d.ts +18 -0
- package/umd/scripts/run-codex-prompts/main/runCoderFix.d.ts +24 -0
- package/umd/scripts/run-codex-prompts/main/runPromptRound.d.ts +12 -2
- package/umd/scripts/run-codex-prompts/prompts/buildPromptRunTraceContent.d.ts +5 -2
- package/umd/scripts/run-codex-prompts/prompts/refreshPromptSelection.d.ts +6 -0
- package/umd/scripts/run-codex-prompts/prompts/writePromptErrorLog.d.ts +4 -0
- package/umd/scripts/run-codex-prompts/prompts/writePromptFile.d.ts +2 -0
- package/umd/scripts/run-codex-prompts/prompts/writePromptRunTrace.d.ts +2 -0
- package/umd/scripts/run-codex-prompts/server/buildCoderServerPromptResponse.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/ui/CoderRunUiState.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/ui/buildCoderCheckRepairUiFrame.d.ts +3 -0
- package/umd/scripts/run-codex-prompts/ui/output/CoderOutputEvent.d.ts +1 -1
- package/umd/scripts/run-codex-prompts/ui/output/CoderRunOutput.d.ts +2 -2
- package/umd/scripts/run-codex-prompts/ui/renderCoderRunUi.d.ts +4 -0
- package/umd/src/cli/cli-commands/coder/add.d.ts +7 -2
- package/umd/src/cli/cli-commands/coder/ensureCoderGitattributesFile.d.ts +13 -0
- package/umd/src/cli/cli-commands/coder/ensureCoderGitignoreFile.d.ts +1 -1
- package/umd/src/cli/cli-commands/coder/fix.d.ts +7 -0
- package/umd/src/cli/cli-commands/coder/fix.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/coder/fixWorkflow.test.d.ts +1 -0
- package/umd/src/cli/cli-commands/coder/initializeCoderProjectConfiguration.d.ts +1 -0
- package/umd/src/cli/cli-commands/coder.d.ts +1 -0
- package/umd/src/cli/cli-commands/common/coderCheckCliOptions.d.ts +1 -1
- package/umd/src/cli/cli-commands/common/ensureProjectTextFile.d.ts +7 -0
- package/umd/src/cli/cli-commands/common/harness/$ensureHarnessInstallations.d.ts +3 -1
- package/umd/src/cli/cli-commands/common/validateCoderRunOptions.d.ts +1 -1
- package/umd/src/cli/cli-commands/common/workspaceRepository.d.ts +12 -0
- package/umd/src/version.d.ts +1 -1
|
@@ -20,12 +20,12 @@ const CODER_ENV_GITIGNORE_RULE = '.env';
|
|
|
20
20
|
const CODER_GITIGNORE_HEADER = '# Promptbook Coder';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Local dependencies and artifacts which every initialized coder project should ignore.
|
|
24
24
|
*/
|
|
25
|
-
const CODER_GITIGNORE_RULES = [PROMPTBOOK_TEMP_GITIGNORE_RULE, CODER_ENV_GITIGNORE_RULE] as const;
|
|
25
|
+
const CODER_GITIGNORE_RULES = [PROMPTBOOK_TEMP_GITIGNORE_RULE, CODER_ENV_GITIGNORE_RULE, 'node_modules'] as const;
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
|
-
* Ensures `.gitignore`
|
|
28
|
+
* Ensures `.gitignore` covers local dependencies, coder artifacts and every supported harness's local artifacts.
|
|
29
29
|
*
|
|
30
30
|
* @private function of `initializeCoderProjectConfiguration`
|
|
31
31
|
*/
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { join } from 'path';
|
|
1
|
+
import { ensureProjectTextFile } from '../common/ensureProjectTextFile';
|
|
3
2
|
import type { InitializationStatus } from './boilerplateTemplates';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -12,24 +11,7 @@ export async function ensureCoderMarkdownFile(
|
|
|
12
11
|
relativeFilePath: string,
|
|
13
12
|
fileContent: string,
|
|
14
13
|
): Promise<InitializationStatus> {
|
|
15
|
-
|
|
16
|
-
if (await isExistingFile(absoluteFilePath)) {
|
|
17
|
-
return 'unchanged';
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
await writeFile(absoluteFilePath, `${fileContent}\n`, 'utf-8');
|
|
21
|
-
return 'created';
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Checks whether a path exists and is a file.
|
|
26
|
-
*/
|
|
27
|
-
async function isExistingFile(path: string): Promise<boolean> {
|
|
28
|
-
try {
|
|
29
|
-
return (await stat(path)).isFile();
|
|
30
|
-
} catch {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
14
|
+
return ensureProjectTextFile(projectPath, relativeFilePath, fileContent);
|
|
33
15
|
}
|
|
34
16
|
|
|
35
17
|
// Note: [🟡] Code for coder init markdown bootstrapping [ensureCoderMarkdownFile](src/cli/cli-commands/coder/ensureCoderMarkdownFile.ts) should never be published outside of `@promptbook/cli`
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { Command as Program } from 'commander';
|
|
2
|
+
import { spaceTrim } from 'spacetrim';
|
|
3
|
+
import type { $side_effect } from '../../../utils/organization/$side_effect';
|
|
4
|
+
import { NotAllowed } from '../../../errors/NotAllowed';
|
|
5
|
+
import { DEFAULT_CODER_CHECK_COMMAND } from '../../../../scripts/run-codex-prompts/checks/CheckBeforeMode';
|
|
6
|
+
import { assertProjectCheckIsConfigured } from '../../../../scripts/run-codex-prompts/checks/projectCheck';
|
|
7
|
+
import { resolveCoderProjectContext } from '../../../../scripts/run-codex-prompts/common/resolveCoderProjectContext';
|
|
8
|
+
import { runCoderFix, validateCoderFixOptions } from '../../../../scripts/run-codex-prompts/main/runCoderFix';
|
|
9
|
+
import { addCoderCheckOptions, normalizeCheckCommandOption } from '../common/coderCheckCliOptions';
|
|
10
|
+
import { $assertSufficientFreeDiskSpace } from '../common/disk-space/$assertSufficientFreeDiskSpace';
|
|
11
|
+
import { handleActionErrors } from '../common/handleActionErrors';
|
|
12
|
+
import { normalizeProjectCliOptions, type ProjectCliOptions } from '../common/projectCliOptions';
|
|
13
|
+
import {
|
|
14
|
+
addPromptRunnerExecutionOptions,
|
|
15
|
+
addPromptRunnerSelectionOptions,
|
|
16
|
+
normalizePromptRunnerCliOptions,
|
|
17
|
+
type PromptRunnerCliOptions,
|
|
18
|
+
} from '../common/promptRunnerCliOptions';
|
|
19
|
+
import {
|
|
20
|
+
addQuestionsOption,
|
|
21
|
+
normalizeQuestionsCliOptions,
|
|
22
|
+
type QuestionsCliOptions,
|
|
23
|
+
} from '../common/questionsCliOptions';
|
|
24
|
+
import { $preflightWorkspaceRepository } from '../common/workspaceRepository';
|
|
25
|
+
import { addWorkspaceRepositoryOptions } from '../common/workspaceRepositoryCliOptions';
|
|
26
|
+
import { addCoderExecutionOptions } from './agentCliOptions';
|
|
27
|
+
import { DEFAULT_WAIT_AFTER_ERROR_MS, parseOptionalWaitDuration } from './waitOptions';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Shared shell convention for an interrupted finite command.
|
|
31
|
+
* @private internal CLI exit convention
|
|
32
|
+
*/
|
|
33
|
+
const INTERRUPTED_EXIT_CODE = 130;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Registers a finite check-repair command with the shared parser, defaults and execution policy.
|
|
37
|
+
* @private internal CLI command registration
|
|
38
|
+
*/
|
|
39
|
+
export function $initializeCoderFixCommand(program: Program): $side_effect {
|
|
40
|
+
const command = program.command('fix').description(
|
|
41
|
+
spaceTrim(`
|
|
42
|
+
Run project checks, repair their failures with one PRD, verify, commit eligible changes, and exit
|
|
43
|
+
|
|
44
|
+
Omitted --check selects npm run check in the selected project. A passing project starts no coding harness.
|
|
45
|
+
Repairs use the project's Developer Book and the selected harness/model; only the selected repair runs.
|
|
46
|
+
Ordinary PRDs and their statuses are left alone. There is no queue, watcher, or planning session.
|
|
47
|
+
Pull and push are explicit opt-ins. --no-commit follows the shared --git-changes ignore constraint.
|
|
48
|
+
Implementation/repair and check changes use separate commits; failed checks retain their genuine outcome.
|
|
49
|
+
Interrupted work is preserved; --git-changes continue cannot resume arbitrary backlog tasks here.
|
|
50
|
+
`),
|
|
51
|
+
);
|
|
52
|
+
command.option('--dry-run', 'Describe the resolved check and possible repair without executing or mutating', false);
|
|
53
|
+
addPromptRunnerSelectionOptions(command);
|
|
54
|
+
addQuestionsOption(command);
|
|
55
|
+
addCoderExecutionOptions(command);
|
|
56
|
+
addCoderCheckOptions(
|
|
57
|
+
command,
|
|
58
|
+
false,
|
|
59
|
+
'Run checks first and verify each repair attempt (default npm run check); persist check changes separately unless --no-commit; quote commands containing flags or shell composition',
|
|
60
|
+
);
|
|
61
|
+
addPromptRunnerExecutionOptions(command);
|
|
62
|
+
command.option('--preserve-logs', 'Keep successful check and repair artifacts', false);
|
|
63
|
+
command.option('--wait-after-error <duration>', 'Delay before bounded execution-error retries (default 10m)');
|
|
64
|
+
addWorkspaceRepositoryOptions(command);
|
|
65
|
+
command.action(
|
|
66
|
+
handleActionErrors(async (cliOptions) => {
|
|
67
|
+
const inputs = cliOptions as PromptRunnerCliOptions &
|
|
68
|
+
QuestionsCliOptions &
|
|
69
|
+
ProjectCliOptions & {
|
|
70
|
+
readonly dryRun: boolean;
|
|
71
|
+
readonly agent?: string;
|
|
72
|
+
readonly context?: string;
|
|
73
|
+
readonly check?: string | string[];
|
|
74
|
+
readonly preserveLogs: boolean;
|
|
75
|
+
readonly waitAfterError?: string;
|
|
76
|
+
};
|
|
77
|
+
const runnerOptions = normalizePromptRunnerCliOptions(inputs, { isAgentRequired: !inputs.dryRun });
|
|
78
|
+
const options = {
|
|
79
|
+
...runnerOptions,
|
|
80
|
+
...normalizeQuestionsCliOptions(inputs),
|
|
81
|
+
dryRun: inputs.dryRun,
|
|
82
|
+
agent: inputs.agent,
|
|
83
|
+
context: inputs.context,
|
|
84
|
+
checkCommand: normalizeCheckCommandOption(inputs.check) ?? DEFAULT_CODER_CHECK_COMMAND,
|
|
85
|
+
preserveLogs: inputs.preserveLogs,
|
|
86
|
+
waitAfterError: parseOptionalWaitDuration(inputs.waitAfterError, DEFAULT_WAIT_AFTER_ERROR_MS),
|
|
87
|
+
};
|
|
88
|
+
if (options.gitChanges === 'continue')
|
|
89
|
+
throw new NotAllowed(
|
|
90
|
+
spaceTrim(`
|
|
91
|
+
\`coder fix\` cannot resume an arbitrary interrupted PRD with \`--git-changes continue\`.
|
|
92
|
+
Inspect the specific repair's saved PRD, trace and changes; commit or recover that work before retrying.
|
|
93
|
+
Use \`--git-changes ignore\` explicitly to preserve existing work while starting a new check job.
|
|
94
|
+
`),
|
|
95
|
+
);
|
|
96
|
+
validateCoderFixOptions(options);
|
|
97
|
+
const projectOptions = normalizeProjectCliOptions(inputs);
|
|
98
|
+
// Read-only discovery lets check configuration fail before an interactive Git initializer can write.
|
|
99
|
+
const inspectedWorkspace = await $preflightWorkspaceRepository({
|
|
100
|
+
...projectOptions,
|
|
101
|
+
policy: 'read-only',
|
|
102
|
+
...options,
|
|
103
|
+
});
|
|
104
|
+
await assertProjectCheckIsConfigured(options.checkCommand, inspectedWorkspace.projectPath);
|
|
105
|
+
const projectContext = await resolveCoderProjectContext({
|
|
106
|
+
projectPath: inspectedWorkspace.projectPath,
|
|
107
|
+
agent: options.agent,
|
|
108
|
+
context: options.context,
|
|
109
|
+
isDefaultAgentDeferred: true,
|
|
110
|
+
});
|
|
111
|
+
const workspace = inputs.dryRun
|
|
112
|
+
? inspectedWorkspace
|
|
113
|
+
: await $preflightWorkspaceRepository({
|
|
114
|
+
projectDirectory: inspectedWorkspace.projectPath,
|
|
115
|
+
policy: 'mutate',
|
|
116
|
+
...options,
|
|
117
|
+
});
|
|
118
|
+
if (!inputs.dryRun) await $assertSufficientFreeDiskSpace(workspace.projectPath);
|
|
119
|
+
const controller = new AbortController();
|
|
120
|
+
/** Cancels owned activity and waits for artifact/lock cleanup before exiting. */
|
|
121
|
+
const cancel = () =>
|
|
122
|
+
controller.abort(
|
|
123
|
+
new NotAllowed('Check repair interrupted; recoverable work and diagnostics were preserved.'),
|
|
124
|
+
);
|
|
125
|
+
if (!inputs.dryRun) {
|
|
126
|
+
process.on('SIGINT', cancel);
|
|
127
|
+
process.on('SIGTERM', cancel);
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
const result = await runCoderFix({ ...options, workspace, projectContext, signal: controller.signal });
|
|
131
|
+
if (inputs.dryRun) return;
|
|
132
|
+
const persistence = options.noCommit
|
|
133
|
+
? 'Eligible changes left uncommitted.'
|
|
134
|
+
: options.autoPush
|
|
135
|
+
? 'Eligible changes committed and pushed, when present.'
|
|
136
|
+
: 'Eligible changes committed, when present.';
|
|
137
|
+
if (result.kind === 'passed-without-repair')
|
|
138
|
+
console.info(`Checks passed without repair. ${persistence}`);
|
|
139
|
+
else if (result.kind === 'repaired-and-verified')
|
|
140
|
+
console.info(`Repaired and verified with \`${options.checkCommand}\`. ${persistence}`);
|
|
141
|
+
else {
|
|
142
|
+
const label =
|
|
143
|
+
result.kind === 'checks-failed'
|
|
144
|
+
? 'Unresolved check failures'
|
|
145
|
+
: result.kind === 'interrupted'
|
|
146
|
+
? 'Check repair interrupted'
|
|
147
|
+
: result.kind === 'persistence-error'
|
|
148
|
+
? `Git/persistence error; checks ${result.isCheckPassed ? 'passed' : 'did not pass'}`
|
|
149
|
+
: result.kind === 'execution-error'
|
|
150
|
+
? 'Check execution error'
|
|
151
|
+
: 'Check repair setup/harness error';
|
|
152
|
+
console.error(`${label}. Ordinary PRDs were not processed.`);
|
|
153
|
+
if (result.repairPrompt) console.error(`Repair artifact: \`${result.repairPrompt.file.path}\`.`);
|
|
154
|
+
console.error(result.error instanceof Error ? result.error.message : String(result.error));
|
|
155
|
+
return process.exit(result.kind === 'interrupted' ? INTERRUPTED_EXIT_CODE : 1);
|
|
156
|
+
}
|
|
157
|
+
} finally {
|
|
158
|
+
process.removeListener('SIGINT', cancel);
|
|
159
|
+
process.removeListener('SIGTERM', cancel);
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Note: [🟡] Code for CLI command [fix](src/cli/cli-commands/coder/fix.ts) should never be published outside of `@promptbook/cli`
|
|
166
|
+
// Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Deterministic offline harness for the installed CLI check-repair contract.
|
|
2
|
+
const FILESYSTEM = require('fs');
|
|
3
|
+
const PATH = require('path');
|
|
4
|
+
const ARGUMENTS = process.argv.slice(2);
|
|
5
|
+
if (ARGUMENTS.includes('--version')) {
|
|
6
|
+
process.stdout.write('codex-cli 0.0.0\n');
|
|
7
|
+
process.exit(0);
|
|
8
|
+
}
|
|
9
|
+
FILESYSTEM.mkdirSync('.promptbook', { recursive: true });
|
|
10
|
+
FILESYSTEM.appendFileSync('.promptbook/harness-invocations', `${ARGUMENTS.join(' ')}\n`);
|
|
11
|
+
if (ARGUMENTS[0] === 'login') {
|
|
12
|
+
process.stdout.write('Logged in using ChatGPT\n');
|
|
13
|
+
process.exit(0);
|
|
14
|
+
}
|
|
15
|
+
if (!ARGUMENTS.includes('exec')) process.exit(2);
|
|
16
|
+
let prompt = '';
|
|
17
|
+
process.stdin.on('data', (chunk) => { prompt += chunk; });
|
|
18
|
+
process.stdin.on('end', () => {
|
|
19
|
+
const projectPath = ARGUMENTS[ARGUMENTS.indexOf('-C') + 1];
|
|
20
|
+
if (PATH.resolve(projectPath) !== process.cwd() || prompt.includes('FORBIDDEN_') ||
|
|
21
|
+
!prompt.includes('Fix the existing project check failures only.')) {
|
|
22
|
+
process.stderr.write('Fixture received wrong project or ordinary task.\n');
|
|
23
|
+
process.exitCode = 2;
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
FILESYSTEM.writeFileSync('.promptbook/mock-call.json', JSON.stringify({ projectPath, prompt }));
|
|
27
|
+
if (!FILESYSTEM.existsSync('.promptbook/keep-failing')) FILESYSTEM.writeFileSync('value.txt', 'fixed');
|
|
28
|
+
process.stdout.write('Verified correction fixture completed.\ntokens used\n0\n');
|
|
29
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// Subprocess-only fixture: machine disk pressure is not an input to CLI parsing/repair smoke tests.
|
|
2
|
+
// The production disk guard and its dedicated unit tests retain the real thresholds.
|
|
3
|
+
const FILE_SYSTEM_PROMISES = require('fs/promises');
|
|
4
|
+
FILE_SYSTEM_PROMISES.statfs = async () => ({ bsize: 4096, bavail: 10000000, blocks: 20000000 });
|
|
@@ -3,6 +3,7 @@ import type { WorkspaceRepositoryContext } from '../common/workspaceRepository';
|
|
|
3
3
|
import { ADAM_AGENT_BOOK_RELATIVE_PATH } from '../common/ensureAdamAgentBook';
|
|
4
4
|
import type { CoderReferencedArtifactStatus } from './coderReferencedArtifacts';
|
|
5
5
|
import { CODER_AGENTS_DIRECTORY_PATH } from './ensureCoderDeveloperAgentFile';
|
|
6
|
+
import { CODER_GITATTRIBUTES_FILE_PATH } from './ensureCoderGitattributesFile';
|
|
6
7
|
import type { CoderInitializationSummary } from './initializeCoderProjectConfiguration';
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -27,6 +28,7 @@ export function getCoderInitializationCommitPaths(
|
|
|
27
28
|
},
|
|
28
29
|
{ relativeFilePath: '.env', status: summary.envFileStatus },
|
|
29
30
|
{ relativeFilePath: '.gitignore', status: summary.gitignoreFileStatus },
|
|
31
|
+
{ relativeFilePath: CODER_GITATTRIBUTES_FILE_PATH, status: summary.gitattributesFileStatus },
|
|
30
32
|
{ relativeFilePath: 'package.json', status: summary.packageJsonFileStatus },
|
|
31
33
|
{ relativeFilePath: '.vscode/settings.json', status: summary.vscodeSettingsFileStatus },
|
|
32
34
|
...summary.referencedArtifactStatuses,
|
|
@@ -29,6 +29,7 @@ import { AGENTS_FILE_PATH } from './agentsFile';
|
|
|
29
29
|
import { DEFAULT_BOILERPLATE_COUNT } from './boilerplateCount';
|
|
30
30
|
import { getDefaultCoderProjectPromptTemplateDefinitions, PROMPTS_DIRECTORY_PATH } from './boilerplateTemplates';
|
|
31
31
|
import { CODER_AGENTS_DIRECTORY_PATH, CODER_DEVELOPER_AGENT_FILE_PATH } from './ensureCoderDeveloperAgentFile';
|
|
32
|
+
import { CODER_GITATTRIBUTES_FILE_PATH } from './ensureCoderGitattributesFile';
|
|
32
33
|
import { isDirectoryEmpty } from './ensureDirectory';
|
|
33
34
|
import { formatDisplayPath } from './formatDisplayPath';
|
|
34
35
|
import { generatePromptBoilerplate } from './generate-boilerplates';
|
|
@@ -79,7 +80,8 @@ export function $initializeCoderInitCommand(program: Program): $side_effect {
|
|
|
79
80
|
- agents/copywriter.book
|
|
80
81
|
- ${CODER_AGENTS_DIRECTORY_PATH}/${ADAM_AGENT_BOOK_RELATIVE_PATH}
|
|
81
82
|
- ${AGENTS_FILE_PATH}
|
|
82
|
-
- .gitignore with local artifacts from every supported harness
|
|
83
|
+
- .gitignore with node_modules and local artifacts from every supported harness
|
|
84
|
+
- ${CODER_GITATTRIBUTES_FILE_PATH} with automatic text detection and LF line endings (existing file is preserved)
|
|
83
85
|
- package.json
|
|
84
86
|
- .vscode/settings.json
|
|
85
87
|
|
|
@@ -10,6 +10,7 @@ import { ensureCoderReferencedArtifacts } from './coderReferencedArtifacts';
|
|
|
10
10
|
import { ensureCoderDefaultAgentFiles } from './ensureCoderDefaultAgentFiles';
|
|
11
11
|
import { CODER_AGENTS_DIRECTORY_PATH } from './ensureCoderDeveloperAgentFile';
|
|
12
12
|
import { ensureCoderEnvFile } from './ensureCoderEnvFile';
|
|
13
|
+
import { CODER_GITATTRIBUTES_FILE_PATH, ensureCoderGitattributesFile } from './ensureCoderGitattributesFile';
|
|
13
14
|
import { ensureCoderGitignoreFile } from './ensureCoderGitignoreFile';
|
|
14
15
|
import { ensureCoderMarkdownFile } from './ensureCoderMarkdownFile';
|
|
15
16
|
import { ensureCoderPackageJsonFile } from './ensureCoderPackageJsonFile';
|
|
@@ -33,6 +34,7 @@ export type CoderInitializationSummary = {
|
|
|
33
34
|
readonly adamAgentFileDiagnostic?: string;
|
|
34
35
|
readonly envFileStatus: InitializationStatus;
|
|
35
36
|
readonly gitignoreFileStatus: InitializationStatus;
|
|
37
|
+
readonly gitattributesFileStatus: InitializationStatus;
|
|
36
38
|
readonly packageJsonFileStatus: InitializationStatus;
|
|
37
39
|
readonly vscodeSettingsFileStatus: InitializationStatus;
|
|
38
40
|
readonly addedPackageJsonScriptNames: ReadonlyArray<string>;
|
|
@@ -91,6 +93,10 @@ export async function initializeCoderProjectConfiguration(
|
|
|
91
93
|
)!;
|
|
92
94
|
const { envFileStatus, initializedEnvVariableNames } = await completeStep('.env', ensureCoderEnvFile(projectPath));
|
|
93
95
|
const gitignoreFileStatus = await completeStep('.gitignore', ensureCoderGitignoreFile(projectPath));
|
|
96
|
+
const gitattributesFileStatus = await completeStep(
|
|
97
|
+
CODER_GITATTRIBUTES_FILE_PATH,
|
|
98
|
+
ensureCoderGitattributesFile(projectPath),
|
|
99
|
+
);
|
|
94
100
|
const {
|
|
95
101
|
status: packageJsonFileStatus,
|
|
96
102
|
addedEntryKeys: addedPackageJsonScriptNames,
|
|
@@ -123,6 +129,7 @@ export async function initializeCoderProjectConfiguration(
|
|
|
123
129
|
adamAgentFileDiagnostic: adamArtifact.diagnostic,
|
|
124
130
|
envFileStatus,
|
|
125
131
|
gitignoreFileStatus,
|
|
132
|
+
gitattributesFileStatus,
|
|
126
133
|
packageJsonFileStatus,
|
|
127
134
|
vscodeSettingsFileStatus,
|
|
128
135
|
addedPackageJsonScriptNames,
|
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
const FILESYSTEM = require('fs');
|
|
3
3
|
const PATH = require('path');
|
|
4
4
|
const ARGUMENTS = process.argv.slice(2);
|
|
5
|
+
if (ARGUMENTS.includes('--version')) {
|
|
6
|
+
process.stdout.write('codex-cli 0.0.0\n');
|
|
7
|
+
process.exit(0);
|
|
8
|
+
}
|
|
5
9
|
if (ARGUMENTS[0] === 'login') {
|
|
6
10
|
process.stdout.write('Logged in using ChatGPT\n');
|
|
7
11
|
process.exit(0);
|
|
@@ -2,6 +2,7 @@ import type { WorkspaceRepositoryContext } from '../common/workspaceRepository';
|
|
|
2
2
|
import colors from 'colors';
|
|
3
3
|
import { ADAM_AGENT_BOOK_RELATIVE_PATH } from '../common/ensureAdamAgentBook';
|
|
4
4
|
import { CODER_AGENTS_DIRECTORY_PATH } from './ensureCoderDeveloperAgentFile';
|
|
5
|
+
import { CODER_GITATTRIBUTES_FILE_PATH } from './ensureCoderGitattributesFile';
|
|
5
6
|
import type { InitializationStatus } from './boilerplateTemplates';
|
|
6
7
|
import type { CoderReferencedArtifactStatus } from './coderReferencedArtifacts';
|
|
7
8
|
import { formatDisplayPath } from './formatDisplayPath';
|
|
@@ -40,6 +41,7 @@ export function printInitializationSummary(
|
|
|
40
41
|
);
|
|
41
42
|
printInitializationStatusLine('.env', summary.envFileStatus);
|
|
42
43
|
printInitializationStatusLine('.gitignore', summary.gitignoreFileStatus);
|
|
44
|
+
printInitializationStatusLine(CODER_GITATTRIBUTES_FILE_PATH, summary.gitattributesFileStatus);
|
|
43
45
|
printInitializationStatusLine('package.json', summary.packageJsonFileStatus);
|
|
44
46
|
printInitializationStatusLine('.vscode/settings.json', summary.vscodeSettingsFileStatus);
|
|
45
47
|
|
|
@@ -281,6 +281,7 @@ export const PROMPTS_README_TEMPLATE = spaceTrim(`
|
|
|
281
281
|
| \`ptbk coder plan --harness openai-codex\` | Interactive planning with the local Developer. Review proposals; \`/save\` writes pending PRDs, \`/draft\` writes not-ready drafts, \`/discard\` drops proposals, \`/exit\` ends. It changes PRD Markdown only and never implements or starts the queue. Currently this planning command supports the Codex harness in a compatible interactive terminal. |
|
|
282
282
|
| \`ptbk coder list\` | Displays fully authored pending tasks grouped by descending priority without execution or file changes. Optional harness/model/agent and priority filters narrow the list. |
|
|
283
283
|
| \`ptbk coder run --harness openai-codex --limit 1 --no-commit --no-auto --check "npm run check"\` | Confirms and implements one selected task, then runs the specified project check. Replace the check command as needed. Without \`--limit\`, execution proceeds through the eligible queue; without \`--no-commit\`, run stages and commits its changes. |
|
|
284
|
+
| \`ptbk coder fix --harness openai-codex\` | Always runs project checks first (default \`npm run check\`), repairs genuine failures with one PRD, verifies and commits eligible changes, then exits. Never selects ordinary queued PRDs. A passing project launches no harness or repair. |
|
|
284
285
|
| \`ptbk coder verify\` | Human review helper: shows completion claims, offers archival or a repair section, and can also ask about pending tasks. It does not run acceptance tests itself. Archival moves the whole file to \`done/\`, so inspect every section before agreeing. There is no separate archive command. |
|
|
285
286
|
| \`ptbk coder find-unwritten\` | Lists pending sections still containing authoring placeholders; not-ready drafts are not included. |
|
|
286
287
|
| \`ptbk coder generate-boilerplates\` | Adds not-ready starter sections using reusable templates; author and review them before making them pending. |
|
|
@@ -301,6 +302,29 @@ export const PROMPTS_README_TEMPLATE = spaceTrim(`
|
|
|
301
302
|
validation before running Coder. Missing checks or setup placeholders stop with setup guidance, without model repairs.
|
|
302
303
|
Direct \`ptbk coder run\` defaults to \`--check-before no\`; checks after prompts remain opt-in. Enabled
|
|
303
304
|
preflight without an explicit command uses \`npm run check\`, including during repair verification.
|
|
305
|
+
|
|
306
|
+
\`ptbk coder fix\` reuses run's check-and-repair phase and stops as soon as that phase finishes. Use
|
|
307
|
+
\`ptbk coder fix --harness openai-codex --check "npm run lint && npm run build && npm test"\` to select
|
|
308
|
+
the project's explicit validation scope. No extra validation command is added. Check failures produce one
|
|
309
|
+
repair PRD under \`prompts/\`; feedback retries update that same task, with at most three repair verification attempts.
|
|
310
|
+
The repair may correct a defective check while preserving its intended validation, but must never weaken
|
|
311
|
+
assertions, lint rules, builds, or thresholds to get a pass. Ordinary PRDs and their statuses are left alone,
|
|
312
|
+
including interrupted tasks. An absent prompts directory is created only when a repair needs its artifact.
|
|
313
|
+
Default Book compilation and harness preparation happen only after a failed check actually needs repair.
|
|
314
|
+
Configure a missing Developer with \`ptbk coder init\` or select a custom Book; an already healthy project
|
|
315
|
+
requires neither a Book nor an installed harness. Explicit Books/context overrides are validated up front.
|
|
316
|
+
Passing formatters/generators commit only their eligible files, with no empty commit and no fabricated PRD.
|
|
317
|
+
Repair checks run after scoped line-ending normalization, verifying the content that will be committed.
|
|
318
|
+
Use \`--no-normalize-line-endings\` for projects that intentionally require other line endings.
|
|
319
|
+
Existing unrelated staged/unstaged files remain outside scoped commits. \`--git-changes ignore\` explicitly
|
|
320
|
+
permits a dirty tree; \`--no-commit\` also requires that option. Pull/push remain explicit \`--auto-pull\` /
|
|
321
|
+
\`--auto-push\` opt-ins. A rejected push leaves the local verified commit available and starts no new repair.
|
|
322
|
+
\`--dry-run\` describes the job without checking, creating tasks, installing tools, calling models or committing.
|
|
323
|
+
\`--no-ui\`, \`--no-questions\` and \`--preserve-logs\` apply to this finite job. Cancellation preserves work
|
|
324
|
+
and diagnostics. \`fix\` rejects \`--git-changes continue\`: inspect/recover the specific saved repair before
|
|
325
|
+
retrying instead of resuming an arbitrary backlog task. Run/server/fix share an exclusive workspace mutation
|
|
326
|
+
lease; inspect a stopped worker's work before explicitly removing a stale lease reported in its diagnostic.
|
|
327
|
+
|
|
304
328
|
Replace retired \`--test\` / \`--test-before\` with \`--check\` / \`--check-before\`. Init migrates recognized
|
|
305
329
|
generated scripts and preserves custom legacy validation in \`check\`. Conflicting definitions or custom callers
|
|
306
330
|
are preserved with manual migration instructions; review them before removing a legacy script.
|
|
@@ -315,7 +339,7 @@ export const PROMPTS_README_TEMPLATE = spaceTrim(`
|
|
|
315
339
|
Init creates local Developer and Planner Books in \`agents/developer.book\` and \`agents/planner.book\`, their
|
|
316
340
|
Lawyer and Copywriter TEAM advisers, and shared \`agents/.core/adam.book\` instructions. Books can
|
|
317
341
|
inherit/import instructions; TEAM entries expose advisers for relevant consultations, not an obligation to
|
|
318
|
-
invoke everyone. \`run\`, \`server\` and \`plan\` default to Developer.
|
|
342
|
+
invoke everyone. \`run\`, \`fix\`, \`server\` and \`plan\` default to Developer.
|
|
319
343
|
\`--agent ./agents/planner.book\` selects Planner explicitly; another Book path also works. \`list\` has no
|
|
320
344
|
default Book filter. Every Book used in \`plan\`, including Developer, still permits planning only.
|
|
321
345
|
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
import { addCoderCheckOptions, normalizeCheckCommandOption } from '../common/coderCheckCliOptions';
|
|
34
34
|
import { DEFAULT_WAIT_AFTER_ERROR_MS, parseOptionalWaitDuration } from './waitOptions';
|
|
35
35
|
import { $ensureCoderHarnessGitignoreRules } from './$ensureCoderHarnessGitignoreRules';
|
|
36
|
+
import { withCoderWorkspaceLock } from '../../../../scripts/run-codex-prompts/common/withCoderWorkspaceLock';
|
|
36
37
|
import { addCoderExecutionOptions, type CoderAgentCliOptions } from './agentCliOptions';
|
|
37
38
|
import { printCoderRunFailure } from './printCoderRunFailure';
|
|
38
39
|
|
|
@@ -75,6 +76,8 @@ export function $initializeCoderRunCommand(program: Program): $side_effect {
|
|
|
75
76
|
- Supports GPG signing of commits
|
|
76
77
|
- Optional pre-coding check run that can stop or repair pre-existing failures
|
|
77
78
|
- Optional post-prompt checks with check-feedback retries
|
|
79
|
+
- Persists implementation and check-produced changes in separate commits, including failed checks
|
|
80
|
+
- Records task completion only after passing checks and required local persistence
|
|
78
81
|
- Progress tracking and interactive P/S/X terminal controls; O changes only the dashboard output view
|
|
79
82
|
- Dry-run mode to preview prompts
|
|
80
83
|
`,
|
|
@@ -97,6 +100,7 @@ export function $initializeCoderRunCommand(program: Program): $side_effect {
|
|
|
97
100
|
spaceTrim(`
|
|
98
101
|
Implement each prompt in its own temporary git worktree with its own isolated environment.
|
|
99
102
|
A verified task is merged back into the branch the coder runs on and the worktree is deleted.
|
|
103
|
+
Fast-forward integration preserves separate implementation, check and finalization commits.
|
|
100
104
|
A task that cannot be merged is marked as failed and its worktree is kept for a manual merge.
|
|
101
105
|
`),
|
|
102
106
|
false,
|
|
@@ -259,16 +263,21 @@ export function $initializeCoderRunCommand(program: Program): $side_effect {
|
|
|
259
263
|
// Check disk space before installations and repository writes; previews require no setup.
|
|
260
264
|
await $assertSufficientFreeDiskSpace(workspace.projectPath);
|
|
261
265
|
|
|
262
|
-
|
|
266
|
+
const isCliUpdated = await withCoderWorkspaceLock(workspace, async () => {
|
|
267
|
+
if (await $ensurePromptbookCliInstallations(questionsOptions, workspace.projectPath)) {
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
await $ensureHarnessInstallations([runnerOptions.agentName], questionsOptions);
|
|
271
|
+
await $ensureCoderHarnessGitignoreRules(
|
|
272
|
+
workspace.projectPath,
|
|
273
|
+
runnerOptions.agentName,
|
|
274
|
+
questionsOptions,
|
|
275
|
+
);
|
|
276
|
+
return false;
|
|
277
|
+
});
|
|
278
|
+
if (isCliUpdated) {
|
|
263
279
|
return process.exit(0);
|
|
264
280
|
}
|
|
265
|
-
|
|
266
|
-
await $ensureHarnessInstallations([runnerOptions.agentName], questionsOptions);
|
|
267
|
-
await $ensureCoderHarnessGitignoreRules(
|
|
268
|
-
workspace.projectPath,
|
|
269
|
-
runnerOptions.agentName,
|
|
270
|
-
questionsOptions,
|
|
271
|
-
);
|
|
272
281
|
}
|
|
273
282
|
|
|
274
283
|
// Note: Import the function dynamically to avoid loading heavy dependencies until needed
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
import { addPromptPriorityOptions } from '../common/promptPriorityCliOptions';
|
|
34
34
|
import { DEFAULT_WAIT_AFTER_ERROR_MS, parseOptionalWaitDuration } from './waitOptions';
|
|
35
35
|
import { $ensureCoderHarnessGitignoreRules } from './$ensureCoderHarnessGitignoreRules';
|
|
36
|
+
import { withCoderWorkspaceLock } from '../../../../scripts/run-codex-prompts/common/withCoderWorkspaceLock';
|
|
36
37
|
import { addCoderExecutionOptions, type CoderAgentCliOptions } from './agentCliOptions';
|
|
37
38
|
import { printCoderRunFailure } from './printCoderRunFailure';
|
|
38
39
|
|
|
@@ -235,12 +236,14 @@ export function $initializeCoderServerCommand(program: Program): $side_effect {
|
|
|
235
236
|
// Check disk space before installations and repository writes; previews require no setup.
|
|
236
237
|
await $assertSufficientFreeDiskSpace(workspace.projectPath);
|
|
237
238
|
|
|
238
|
-
await
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
239
|
+
await withCoderWorkspaceLock(workspace, async () => {
|
|
240
|
+
await $ensureHarnessInstallations([runnerOptions.agentName], questionsOptions);
|
|
241
|
+
await $ensureCoderHarnessGitignoreRules(
|
|
242
|
+
workspace.projectPath,
|
|
243
|
+
runnerOptions.agentName,
|
|
244
|
+
questionsOptions,
|
|
245
|
+
);
|
|
246
|
+
});
|
|
244
247
|
}
|
|
245
248
|
|
|
246
249
|
// Note: Import dynamically to avoid loading heavy dependencies until needed
|
|
@@ -15,6 +15,7 @@ import { $initializeCoderListCommand } from './coder/list';
|
|
|
15
15
|
import { $initializeCoderPingCommand } from './coder/ping';
|
|
16
16
|
import { $initializeCoderPlanCommand } from './coder/plan';
|
|
17
17
|
import { $initializeCoderRunCommand } from './coder/run';
|
|
18
|
+
import { $initializeCoderFixCommand } from './coder/fix';
|
|
18
19
|
import { $initializeCoderServerCommand } from './coder/server';
|
|
19
20
|
import { $initializeCoderVerifyCommand } from './coder/verify';
|
|
20
21
|
|
|
@@ -29,6 +30,7 @@ import { $initializeCoderVerifyCommand } from './coder/verify';
|
|
|
29
30
|
* - find-refactor-candidates: Find files that need refactoring
|
|
30
31
|
* - list: List ready prompts in priority order without running them
|
|
31
32
|
* - run: Run coding prompts with AI agents
|
|
33
|
+
* - fix: Check and repair the project, then exit without processing the queue
|
|
32
34
|
* - ping: Test one harness and model with a tiny dummy prompt
|
|
33
35
|
* - verify: Verify completed prompts
|
|
34
36
|
* - find-fresh-emoji-tags: Find unused emoji tags
|
|
@@ -52,6 +54,7 @@ export function $initializeCoderCommand(program: Program): $side_effect {
|
|
|
52
54
|
- find-unwritten: List prompt sections that still need to be authored
|
|
53
55
|
- list: List ready prompts in priority order without running them
|
|
54
56
|
- run: Run coding prompts with AI agents
|
|
57
|
+
- fix: Check and repair the project, then exit without processing the queue
|
|
55
58
|
- ping: Test the connection, response time and quota of one harness and model
|
|
56
59
|
- server: Start a long-running coder server with a kanban web UI
|
|
57
60
|
- verify: Verify completed prompts
|
|
@@ -70,6 +73,7 @@ export function $initializeCoderCommand(program: Program): $side_effect {
|
|
|
70
73
|
$initializeCoderFindUnwrittenCommand(coderCommand);
|
|
71
74
|
$initializeCoderListCommand(coderCommand);
|
|
72
75
|
$initializeCoderRunCommand(coderCommand);
|
|
76
|
+
$initializeCoderFixCommand(coderCommand);
|
|
73
77
|
$initializeCoderPingCommand(coderCommand);
|
|
74
78
|
$initializeCoderServerCommand(coderCommand);
|
|
75
79
|
$initializeCoderVerifyCommand(coderCommand);
|
|
@@ -35,18 +35,19 @@ export const LEGACY_CODER_CHECK_OPTIONS = [
|
|
|
35
35
|
* Registers the shared project check command and rejects retired aggregate-test spellings.
|
|
36
36
|
* @private shared CLI registration for Coder execution
|
|
37
37
|
*/
|
|
38
|
-
export function addCoderCheckOptions(
|
|
39
|
-
command
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
export function addCoderCheckOptions(
|
|
39
|
+
command: Command,
|
|
40
|
+
isCheckBeforeSupported: boolean,
|
|
41
|
+
description = 'Run project checks after each prompt; commit eligible check changes separately unless --no-commit; quote commands containing flags or shell composition',
|
|
42
|
+
): void {
|
|
43
|
+
command.option('--check <check-command...>', description);
|
|
43
44
|
if (isCheckBeforeSupported) {
|
|
44
45
|
command.addOption(
|
|
45
46
|
new Option(
|
|
46
47
|
'--check-before <mode>',
|
|
47
48
|
`Check before coding: ${CHECK_BEFORE_MODE_VALUES.join(
|
|
48
49
|
', ',
|
|
49
|
-
)} (defaults to no; uses npm run check when --check is omitted)`,
|
|
50
|
+
)} (defaults to no; uses npm run check when --check is omitted; both enabled modes commit eligible check changes separately unless --no-commit)`,
|
|
50
51
|
)
|
|
51
52
|
.choices([...CHECK_BEFORE_MODE_VALUES])
|
|
52
53
|
.default('no'),
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { stat, writeFile } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import type { ProjectInitializationStatus } from './projectInitialization';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates one project text file with default content, preserving any existing file.
|
|
7
|
+
*
|
|
8
|
+
* @private internal utility of Promptbook CLI project initialization
|
|
9
|
+
*/
|
|
10
|
+
export async function ensureProjectTextFile(
|
|
11
|
+
projectPath: string,
|
|
12
|
+
relativeFilePath: string,
|
|
13
|
+
fileContent: string,
|
|
14
|
+
): Promise<ProjectInitializationStatus> {
|
|
15
|
+
const absoluteFilePath = join(projectPath, relativeFilePath);
|
|
16
|
+
if (await isExistingFile(absoluteFilePath)) {
|
|
17
|
+
return 'unchanged';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
await writeFile(absoluteFilePath, `${fileContent}\n`, 'utf-8');
|
|
21
|
+
return 'created';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Checks whether a path exists and is a file.
|
|
26
|
+
*/
|
|
27
|
+
async function isExistingFile(path: string): Promise<boolean> {
|
|
28
|
+
try {
|
|
29
|
+
return (await stat(path)).isFile();
|
|
30
|
+
} catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Note: [🟡] Code for project text file bootstrapping [ensureProjectTextFile](src/cli/cli-commands/common/ensureProjectTextFile.ts) should never be published outside of `@promptbook/cli`
|
|
@@ -4,6 +4,8 @@ import { $applyHarnessInstallationStatus } from './$applyHarnessInstallationStat
|
|
|
4
4
|
import { $checkHarnessInstallation } from './$checkHarnessInstallation';
|
|
5
5
|
import type { HarnessDefinition } from './HarnessDefinition';
|
|
6
6
|
import { getHarnessDefinition } from './HarnessDefinition';
|
|
7
|
+
import { buildHarnessInstallCommand } from './buildHarnessInstallCommand';
|
|
8
|
+
import { NotAllowed } from '../../../../errors/NotAllowed';
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* Checks that every given CLI coding harness is installed globally and, when the questions are enabled, up to date.
|
|
@@ -19,6 +21,7 @@ import { getHarnessDefinition } from './HarnessDefinition';
|
|
|
19
21
|
export async function $ensureHarnessInstallations(
|
|
20
22
|
harnessNames: ReadonlyArray<PromptRunnerHarnessName | undefined>,
|
|
21
23
|
questionsOptions: NormalizedQuestionsCliOptions,
|
|
24
|
+
options: { readonly isRequired?: boolean } = {},
|
|
22
25
|
): Promise<void> {
|
|
23
26
|
const definitions = resolveCheckedHarnessDefinitions(harnessNames);
|
|
24
27
|
|
|
@@ -37,6 +40,16 @@ export async function $ensureHarnessInstallations(
|
|
|
37
40
|
|
|
38
41
|
for (const status of statuses) {
|
|
39
42
|
await $applyHarnessInstallationStatus(status, questionsOptions);
|
|
43
|
+
if (options.isRequired && status.installationState === 'not-installed') {
|
|
44
|
+
const rechecked = await $checkHarnessInstallation(status.definition, false);
|
|
45
|
+
if (rechecked.installationState === 'not-installed') {
|
|
46
|
+
throw new NotAllowed(
|
|
47
|
+
`Repair requires ${status.definition.label}. Install it with \`${buildHarnessInstallCommand(
|
|
48
|
+
status.definition,
|
|
49
|
+
)}\`, then retry. No other task was executed.`,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
40
53
|
}
|
|
41
54
|
}
|
|
42
55
|
|
|
@@ -8,7 +8,22 @@ import { NotAllowed } from '../../../errors/NotAllowed';
|
|
|
8
8
|
* Validates cross-flag constraints before workspace setup or the run starts.
|
|
9
9
|
* @private shared validation for Coder execution commands
|
|
10
10
|
*/
|
|
11
|
-
export function validateCoderRunOptions(
|
|
11
|
+
export function validateCoderRunOptions(
|
|
12
|
+
options: Pick<
|
|
13
|
+
RunOptions,
|
|
14
|
+
| 'checkCommand'
|
|
15
|
+
| 'checkBefore'
|
|
16
|
+
| 'allowDestructiveAutoMigrate'
|
|
17
|
+
| 'autoMigrate'
|
|
18
|
+
| 'noCommit'
|
|
19
|
+
| 'waitForUser'
|
|
20
|
+
| 'gitChanges'
|
|
21
|
+
| 'autoPull'
|
|
22
|
+
| 'dryRun'
|
|
23
|
+
| 'isIsolated'
|
|
24
|
+
| 'limit'
|
|
25
|
+
>,
|
|
26
|
+
): void {
|
|
12
27
|
if (options.checkCommand !== undefined && !options.checkCommand.trim()) {
|
|
13
28
|
throw new NotAllowed(
|
|
14
29
|
spaceTrim(`
|