@eldrforge/kodrdriv 1.2.1 → 1.2.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/dist/application.js +7 -19
- package/dist/application.js.map +1 -1
- package/dist/arguments.js +345 -96
- package/dist/arguments.js.map +1 -1
- package/dist/commands/clean.js +1 -1
- package/dist/commands/clean.js.map +1 -1
- package/dist/commands/commit.js +59 -14
- package/dist/commands/commit.js.map +1 -1
- package/dist/commands/link.js +200 -11
- package/dist/commands/link.js.map +1 -1
- package/dist/commands/release.js +9 -3
- package/dist/commands/release.js.map +1 -1
- package/dist/commands/review.js +356 -145
- package/dist/commands/review.js.map +1 -1
- package/dist/commands/tree.js +111 -250
- package/dist/commands/tree.js.map +1 -1
- package/dist/commands/unlink.js +238 -10
- package/dist/commands/unlink.js.map +1 -1
- package/dist/constants.js +28 -12
- package/dist/constants.js.map +1 -1
- package/dist/content/issues.js +1 -1
- package/dist/error/CommandErrors.js +8 -1
- package/dist/error/CommandErrors.js.map +1 -1
- package/dist/prompt/commit.js +6 -0
- package/dist/prompt/commit.js.map +1 -1
- package/dist/prompt/instructions/review.md +13 -3
- package/dist/util/openai.js +70 -9
- package/dist/util/openai.js.map +1 -1
- package/dist/util/validation.js +24 -1
- package/dist/util/validation.js.map +1 -1
- package/package.json +2 -2
- package/test-external-unlink/package.json +16 -0
- package/test-externals/package.json +8 -0
- package/test-review-flow.sh +15 -0
- package/test-sort-files/alpha.md +3 -0
- package/test-sort-files/middle.txt +3 -0
- package/test-sort-files/zebra.txt +3 -0
- package/test_output.txt +161 -0
- package/dist/types.js +0 -140
- package/dist/types.js.map +0 -1
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["import { MergeMethod } from './types';\nimport os from 'os';\nimport path from 'path';\n\nexport const VERSION = '__VERSION__ (__GIT_BRANCH__/__GIT_COMMIT__ __GIT_TAGS__ __GIT_COMMIT_DATE__) __SYSTEM_INFO__';\nexport const PROGRAM_NAME = 'kodrdriv';\nexport const DEFAULT_CHARACTER_ENCODING = 'utf-8';\nexport const DEFAULT_BINARY_TO_TEXT_ENCODING = 'base64';\nexport const DEFAULT_DIFF = true;\nexport const DEFAULT_LOG = false;\nexport const DEFAULT_OVERRIDES = false;\nexport const DATE_FORMAT_MONTH_DAY = 'MM-DD';\nexport const DATE_FORMAT_YEAR = 'YYYY';\nexport const DATE_FORMAT_YEAR_MONTH = 'YYYY-MM';\nexport const DATE_FORMAT_YEAR_MONTH_DAY = 'YYYY-MM-DD';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_SLASH = 'YYYY/MM/DD';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES = 'YYYY-MM-DD-HHmm';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS = 'YYYY-MM-DD-HHmmss';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS = 'YYYY-MM-DD-HHmmss.SSS';\nexport const DATE_FORMAT_SHORT_TIMESTAMP = 'YYMMdd-HHmm';\nexport const DATE_FORMAT_MONTH = 'MM';\nexport const DATE_FORMAT_DAY = 'DD';\nexport const DATE_FORMAT_HOURS = 'HHmm';\nexport const DATE_FORMAT_MINUTES = 'mm';\nexport const DATE_FORMAT_SECONDS = 'ss';\nexport const DATE_FORMAT_MILLISECONDS = 'SSS';\nexport const DEFAULT_VERBOSE = false;\nexport const DEFAULT_DRY_RUN = false;\nexport const DEFAULT_DEBUG = false;\nexport const DEFAULT_MODEL = 'gpt-4o-mini';\nexport const DEFAULT_MODEL_STRONG = 'gpt-4o';\nexport const DEFAULT_OUTPUT_DIRECTORY = 'output/kodrdriv';\n\n// Buffer size for git commands that may produce large output (like git log)\nexport const DEFAULT_GIT_COMMAND_MAX_BUFFER = 50 * 1024 * 1024; // 50MB\n\nexport const DEFAULT_CONTEXT_DIRECTORIES: string[] = [];\n\nexport const DEFAULT_CONFIG_DIR = '.kodrdriv';\nexport const DEFAULT_PREFERENCES_DIRECTORY = path.join(os.homedir(), '.kodrdriv');\n\nexport const DEFAULT_FROM_COMMIT_ALIAS = 'main';\nexport const DEFAULT_TO_COMMIT_ALIAS = 'HEAD';\n\nexport const DEFAULT_ADD = false;\nexport const DEFAULT_CACHED = false;\nexport const DEFAULT_SENDIT_MODE = false;\nexport const DEFAULT_INTERACTIVE_MODE = false;\nexport const DEFAULT_AMEND_MODE = false;\nexport const DEFAULT_MESSAGE_LIMIT = 50;\nexport const DEFAULT_MAX_DIFF_BYTES = 20480; // 20KB limit per file\n\nexport const DEFAULT_MERGE_METHOD: MergeMethod = 'squash';\n\nexport const DEFAULT_EXCLUDED_PATTERNS = [\n 'node_modules', 'package-lock.json', 'yarn.lock', 'bun.lockb',\n 'composer.lock', 'Cargo.lock', 'Gemfile.lock',\n 'dist', 'build', 'out', '.next', '.nuxt', 'coverage',\n '.vscode', '.idea', '.DS_Store', '.git', '.gitignore',\n 'logs', 'tmp', '.cache', '*.log', '.env', '.env.*',\n '*.pem', '*.crt', '*.key', '*.sqlite', '*.db',\n '*.zip', '*.tar', '*.gz', '*.exe', '*.bin'\n];\n\nexport const COMMAND_COMMIT = 'commit';\nexport const COMMAND_AUDIO_COMMIT = 'audio-commit';\nexport const COMMAND_SELECT_AUDIO = 'select-audio';\nexport const COMMAND_RELEASE = 'release';\nexport const COMMAND_REVIEW = 'review';\nexport const COMMAND_AUDIO_REVIEW = 'audio-review';\nexport const COMMAND_PUBLISH = 'publish';\nexport const COMMAND_TREE = 'tree';\nexport const COMMAND_LINK = 'link';\nexport const COMMAND_UNLINK = 'unlink';\nexport const COMMAND_CLEAN = 'clean';\nexport const COMMAND_DEVELOPMENT = 'development';\nexport const COMMAND_VERSIONS = 'versions';\nexport const COMMAND_CHECK_CONFIG = 'check-config';\nexport const COMMAND_INIT_CONFIG = 'init-config';\n\nexport const ALLOWED_COMMANDS = [\n COMMAND_COMMIT,\n COMMAND_AUDIO_COMMIT,\n COMMAND_SELECT_AUDIO,\n COMMAND_RELEASE,\n COMMAND_REVIEW,\n COMMAND_AUDIO_REVIEW,\n COMMAND_PUBLISH,\n COMMAND_TREE,\n COMMAND_LINK,\n COMMAND_UNLINK,\n COMMAND_CLEAN,\n COMMAND_DEVELOPMENT,\n COMMAND_VERSIONS\n];\n\nexport const DEFAULT_COMMAND = COMMAND_COMMIT;\n\nexport const DEFAULT_INSTRUCTIONS_DIR = `instructions`;\n\nexport const DEFAULT_PERSONA_DIR = `personas`;\n\nexport const DEFAULT_INSTRUCTIONS_COMMIT_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/commit.md`;\nexport const DEFAULT_INSTRUCTIONS_RELEASE_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/release.md`;\nexport const DEFAULT_INSTRUCTIONS_REVIEW_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/review.md`;\n\nexport const DEFAULT_PERSONA_RELEASER_FILE = `${DEFAULT_PERSONA_DIR}/releaser.md`;\nexport const DEFAULT_PERSONA_YOU_FILE = `${DEFAULT_PERSONA_DIR}/you.md`;\n\n// Default instructions for each persona\nexport const DEFAULT_INSTRUCTIONS_MAP = {\n [COMMAND_COMMIT]: DEFAULT_INSTRUCTIONS_COMMIT_FILE,\n [COMMAND_AUDIO_COMMIT]: DEFAULT_INSTRUCTIONS_COMMIT_FILE, // Reuse commit instructions\n [COMMAND_RELEASE]: DEFAULT_INSTRUCTIONS_RELEASE_FILE,\n [COMMAND_REVIEW]: DEFAULT_INSTRUCTIONS_REVIEW_FILE, // Reuse audio-review instructions for now\n [COMMAND_AUDIO_REVIEW]: DEFAULT_INSTRUCTIONS_REVIEW_FILE,\n};\n\n// Default personas for each command\nexport const DEFAULT_PERSONA_MAP = {\n [COMMAND_COMMIT]: DEFAULT_PERSONA_YOU_FILE,\n [COMMAND_AUDIO_COMMIT]: DEFAULT_PERSONA_YOU_FILE, // Use You persona\n [COMMAND_RELEASE]: DEFAULT_PERSONA_RELEASER_FILE,\n [COMMAND_REVIEW]: DEFAULT_PERSONA_YOU_FILE, // Use You persona\n [COMMAND_AUDIO_REVIEW]: DEFAULT_PERSONA_YOU_FILE,\n};\n\n// Used by child process to create paths\nexport const DEFAULT_PATH_SEPARATOR = '/';\n\n// Used by util/general for file filtering\nexport const DEFAULT_IGNORE_PATTERNS = [\n 'node_modules/**',\n '**/*.log',\n '.git/**',\n 'dist/**',\n 'build/**',\n 'coverage/**',\n '.DS_Store',\n '*.tmp',\n '*.cache',\n];\n\n// Used by util/storage for directory names\nexport const DEFAULT_DIRECTORY_PREFIX = '.kodrdriv';\n\n// Used by other commands but not exposed in CLI\nexport const INTERNAL_DEFAULT_OUTPUT_FILE = 'output.txt';\n\nexport const INTERNAL_DATETIME_FORMAT = 'YYYY-MM-DD_HH-mm-ss';\n\n// Define defaults in one place\nexport const KODRDRIV_DEFAULTS = {\n dryRun: DEFAULT_DRY_RUN,\n verbose: DEFAULT_VERBOSE,\n debug: DEFAULT_DEBUG,\n overrides: DEFAULT_OVERRIDES,\n model: DEFAULT_MODEL,\n contextDirectories: DEFAULT_CONTEXT_DIRECTORIES,\n commandName: DEFAULT_COMMAND,\n configDirectory: DEFAULT_CONFIG_DIR,\n outputDirectory: DEFAULT_OUTPUT_DIRECTORY,\n preferencesDirectory: DEFAULT_PREFERENCES_DIRECTORY,\n commit: {\n add: DEFAULT_ADD,\n cached: DEFAULT_CACHED,\n sendit: DEFAULT_SENDIT_MODE,\n interactive: DEFAULT_INTERACTIVE_MODE,\n amend: DEFAULT_AMEND_MODE,\n messageLimit: DEFAULT_MESSAGE_LIMIT,\n skipFileCheck: false,\n maxDiffBytes: DEFAULT_MAX_DIFF_BYTES,\n },\n release: {\n from: DEFAULT_FROM_COMMIT_ALIAS,\n to: DEFAULT_TO_COMMIT_ALIAS,\n messageLimit: DEFAULT_MESSAGE_LIMIT,\n interactive: DEFAULT_INTERACTIVE_MODE,\n maxDiffBytes: DEFAULT_MAX_DIFF_BYTES,\n noMilestones: false,\n },\n audioCommit: {\n maxRecordingTime: 300, // 5 minutes default\n audioDevice: undefined, // Auto-detect by default\n },\n review: {\n includeCommitHistory: true,\n includeRecentDiffs: true,\n includeReleaseNotes: false,\n includeGithubIssues: true,\n commitHistoryLimit: 10,\n diffHistoryLimit: 5,\n releaseNotesLimit: 3,\n githubIssuesLimit: 20,\n sendit: DEFAULT_SENDIT_MODE,\n },\n audioReview: {\n includeCommitHistory: true,\n includeRecentDiffs: true,\n includeReleaseNotes: false,\n includeGithubIssues: true,\n commitHistoryLimit: 10,\n diffHistoryLimit: 5,\n releaseNotesLimit: 3,\n githubIssuesLimit: 20,\n sendit: DEFAULT_SENDIT_MODE,\n maxRecordingTime: 300, // 5 minutes default\n audioDevice: undefined, // Auto-detect by default\n directory: undefined, // No default directory\n },\n publish: {\n mergeMethod: DEFAULT_MERGE_METHOD,\n from: DEFAULT_FROM_COMMIT_ALIAS,\n targetVersion: 'patch',\n interactive: DEFAULT_INTERACTIVE_MODE,\n requiredEnvVars: ['GITHUB_TOKEN', 'OPENAI_API_KEY'],\n linkWorkspacePackages: true,\n unlinkWorkspacePackages: true,\n sendit: DEFAULT_SENDIT_MODE,\n targetBranch: 'main',\n noMilestones: false,\n },\n link: {\n scopeRoots: {},\n dryRun: false,\n packageArgument: undefined,\n },\n unlink: {\n scopeRoots: {},\n workspaceFile: undefined,\n dryRun: false,\n cleanNodeModules: false,\n packageArgument: undefined,\n },\n tree: {\n directories: undefined,\n excludedPatterns: undefined,\n startFrom: undefined,\n stopAt: undefined,\n cmd: undefined,\n parallel: false,\n builtInCommand: undefined,\n continue: false,\n packageArgument: undefined,\n cleanNodeModules: false,\n },\n development: {\n targetVersion: 'patch',\n noMilestones: false,\n },\n versions: {\n subcommand: undefined,\n directories: undefined,\n },\n excludedPatterns: DEFAULT_EXCLUDED_PATTERNS,\n};\n"],"names":["VERSION","PROGRAM_NAME","DEFAULT_OVERRIDES","DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS","DEFAULT_VERBOSE","DEFAULT_DRY_RUN","DEFAULT_DEBUG","DEFAULT_MODEL","DEFAULT_OUTPUT_DIRECTORY","DEFAULT_GIT_COMMAND_MAX_BUFFER","DEFAULT_CONTEXT_DIRECTORIES","DEFAULT_CONFIG_DIR","DEFAULT_PREFERENCES_DIRECTORY","path","join","os","homedir","DEFAULT_FROM_COMMIT_ALIAS","DEFAULT_TO_COMMIT_ALIAS","DEFAULT_ADD","DEFAULT_CACHED","DEFAULT_SENDIT_MODE","DEFAULT_INTERACTIVE_MODE","DEFAULT_AMEND_MODE","DEFAULT_MESSAGE_LIMIT","DEFAULT_MAX_DIFF_BYTES","DEFAULT_MERGE_METHOD","DEFAULT_EXCLUDED_PATTERNS","COMMAND_COMMIT","COMMAND_AUDIO_COMMIT","COMMAND_SELECT_AUDIO","COMMAND_RELEASE","COMMAND_REVIEW","COMMAND_AUDIO_REVIEW","COMMAND_PUBLISH","COMMAND_TREE","COMMAND_LINK","COMMAND_UNLINK","COMMAND_CLEAN","COMMAND_DEVELOPMENT","COMMAND_VERSIONS","COMMAND_CHECK_CONFIG","COMMAND_INIT_CONFIG","ALLOWED_COMMANDS","DEFAULT_COMMAND","KODRDRIV_DEFAULTS","dryRun","verbose","debug","overrides","model","contextDirectories","commandName","configDirectory","outputDirectory","preferencesDirectory","commit","add","cached","sendit","interactive","amend","messageLimit","skipFileCheck","maxDiffBytes","release","from","to","noMilestones","audioCommit","maxRecordingTime","audioDevice","undefined","review","includeCommitHistory","includeRecentDiffs","includeReleaseNotes","includeGithubIssues","commitHistoryLimit","diffHistoryLimit","releaseNotesLimit","githubIssuesLimit","audioReview","directory","publish","mergeMethod","targetVersion","requiredEnvVars","linkWorkspacePackages","unlinkWorkspacePackages","targetBranch","link","scopeRoots","packageArgument","unlink","workspaceFile","cleanNodeModules","tree","directories","excludedPatterns","startFrom","stopAt","cmd","parallel","builtInCommand","continue","development","versions","subcommand"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["import { MergeMethod } from './types';\nimport os from 'os';\nimport path from 'path';\n\nexport const VERSION = '__VERSION__ (__GIT_BRANCH__/__GIT_COMMIT__ __GIT_TAGS__ __GIT_COMMIT_DATE__) __SYSTEM_INFO__';\nexport const PROGRAM_NAME = 'kodrdriv';\nexport const DEFAULT_CHARACTER_ENCODING = 'utf-8';\nexport const DEFAULT_BINARY_TO_TEXT_ENCODING = 'base64';\nexport const DEFAULT_DIFF = true;\nexport const DEFAULT_LOG = false;\nexport const DEFAULT_OVERRIDES = false;\nexport const DATE_FORMAT_MONTH_DAY = 'MM-DD';\nexport const DATE_FORMAT_YEAR = 'YYYY';\nexport const DATE_FORMAT_YEAR_MONTH = 'YYYY-MM';\nexport const DATE_FORMAT_YEAR_MONTH_DAY = 'YYYY-MM-DD';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_SLASH = 'YYYY/MM/DD';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES = 'YYYY-MM-DD-HHmm';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS = 'YYYY-MM-DD-HHmmss';\nexport const DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS = 'YYYY-MM-DD-HHmmss.SSS';\nexport const DATE_FORMAT_SHORT_TIMESTAMP = 'YYMMdd-HHmm';\nexport const DATE_FORMAT_MONTH = 'MM';\nexport const DATE_FORMAT_DAY = 'DD';\nexport const DATE_FORMAT_HOURS = 'HHmm';\nexport const DATE_FORMAT_MINUTES = 'mm';\nexport const DATE_FORMAT_SECONDS = 'ss';\nexport const DATE_FORMAT_MILLISECONDS = 'SSS';\nexport const DEFAULT_VERBOSE = false;\nexport const DEFAULT_DRY_RUN = false;\nexport const DEFAULT_DEBUG = false;\nexport const DEFAULT_MODEL = 'gpt-4o-mini';\nexport const DEFAULT_MODEL_STRONG = 'gpt-4o';\nexport const DEFAULT_OPENAI_REASONING = 'low';\nexport const DEFAULT_OPENAI_MAX_OUTPUT_TOKENS = 10000;\nexport const DEFAULT_OUTPUT_DIRECTORY = 'output/kodrdriv';\n\n// Buffer size for git commands that may produce large output (like git log)\nexport const DEFAULT_GIT_COMMAND_MAX_BUFFER = 50 * 1024 * 1024; // 50MB\n\nexport const DEFAULT_CONTEXT_DIRECTORIES: string[] = [];\n\nexport const DEFAULT_CONFIG_DIR = '.kodrdriv';\nexport const DEFAULT_PREFERENCES_DIRECTORY = path.join(os.homedir(), '.kodrdriv');\n\nexport const DEFAULT_FROM_COMMIT_ALIAS = 'main';\nexport const DEFAULT_TO_COMMIT_ALIAS = 'HEAD';\n\nexport const DEFAULT_ADD = false;\nexport const DEFAULT_CACHED = false;\nexport const DEFAULT_SENDIT_MODE = false;\nexport const DEFAULT_INTERACTIVE_MODE = false;\nexport const DEFAULT_AMEND_MODE = false;\nexport const DEFAULT_MESSAGE_LIMIT = 50;\nexport const DEFAULT_MAX_DIFF_BYTES = 20480; // 20KB limit per file\n\nexport const DEFAULT_MERGE_METHOD: MergeMethod = 'squash';\n\nexport const DEFAULT_EXCLUDED_PATTERNS = [\n 'node_modules', 'package-lock.json', 'yarn.lock', 'bun.lockb',\n 'composer.lock', 'Cargo.lock', 'Gemfile.lock',\n 'dist', 'build', 'out', '.next', '.nuxt', 'coverage',\n '.vscode', '.idea', '.DS_Store', '.git', '.gitignore',\n 'logs', 'tmp', '.cache', '*.log', '.env', '.env.*',\n '*.pem', '*.crt', '*.key', '*.sqlite', '*.db',\n '*.zip', '*.tar', '*.gz', '*.exe', '*.bin'\n];\n\nexport const COMMAND_COMMIT = 'commit';\nexport const COMMAND_AUDIO_COMMIT = 'audio-commit';\nexport const COMMAND_SELECT_AUDIO = 'select-audio';\nexport const COMMAND_RELEASE = 'release';\nexport const COMMAND_REVIEW = 'review';\nexport const COMMAND_AUDIO_REVIEW = 'audio-review';\nexport const COMMAND_PUBLISH = 'publish';\nexport const COMMAND_TREE = 'tree';\nexport const COMMAND_LINK = 'link';\nexport const COMMAND_UNLINK = 'unlink';\nexport const COMMAND_CLEAN = 'clean';\nexport const COMMAND_DEVELOPMENT = 'development';\nexport const COMMAND_VERSIONS = 'versions';\nexport const COMMAND_CHECK_CONFIG = 'check-config';\nexport const COMMAND_INIT_CONFIG = 'init-config';\n\nexport const ALLOWED_COMMANDS = [\n COMMAND_COMMIT,\n COMMAND_AUDIO_COMMIT,\n COMMAND_SELECT_AUDIO,\n COMMAND_RELEASE,\n COMMAND_REVIEW,\n COMMAND_AUDIO_REVIEW,\n COMMAND_PUBLISH,\n COMMAND_TREE,\n COMMAND_LINK,\n COMMAND_UNLINK,\n COMMAND_CLEAN,\n COMMAND_DEVELOPMENT,\n COMMAND_VERSIONS\n];\n\nexport const DEFAULT_COMMAND = COMMAND_COMMIT;\n\nexport const DEFAULT_INSTRUCTIONS_DIR = `instructions`;\n\nexport const DEFAULT_PERSONA_DIR = `personas`;\n\nexport const DEFAULT_INSTRUCTIONS_COMMIT_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/commit.md`;\nexport const DEFAULT_INSTRUCTIONS_RELEASE_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/release.md`;\nexport const DEFAULT_INSTRUCTIONS_REVIEW_FILE = `${DEFAULT_INSTRUCTIONS_DIR}/review.md`;\n\nexport const DEFAULT_PERSONA_RELEASER_FILE = `${DEFAULT_PERSONA_DIR}/releaser.md`;\nexport const DEFAULT_PERSONA_YOU_FILE = `${DEFAULT_PERSONA_DIR}/you.md`;\n\n// Default instructions for each persona\nexport const DEFAULT_INSTRUCTIONS_MAP = {\n [COMMAND_COMMIT]: DEFAULT_INSTRUCTIONS_COMMIT_FILE,\n [COMMAND_AUDIO_COMMIT]: DEFAULT_INSTRUCTIONS_COMMIT_FILE, // Reuse commit instructions\n [COMMAND_RELEASE]: DEFAULT_INSTRUCTIONS_RELEASE_FILE,\n [COMMAND_REVIEW]: DEFAULT_INSTRUCTIONS_REVIEW_FILE, // Reuse audio-review instructions for now\n [COMMAND_AUDIO_REVIEW]: DEFAULT_INSTRUCTIONS_REVIEW_FILE,\n};\n\n// Default personas for each command\nexport const DEFAULT_PERSONA_MAP = {\n [COMMAND_COMMIT]: DEFAULT_PERSONA_YOU_FILE,\n [COMMAND_AUDIO_COMMIT]: DEFAULT_PERSONA_YOU_FILE, // Use You persona\n [COMMAND_RELEASE]: DEFAULT_PERSONA_RELEASER_FILE,\n [COMMAND_REVIEW]: DEFAULT_PERSONA_YOU_FILE, // Use You persona\n [COMMAND_AUDIO_REVIEW]: DEFAULT_PERSONA_YOU_FILE,\n};\n\n// Used by child process to create paths\nexport const DEFAULT_PATH_SEPARATOR = '/';\n\n// Used by util/general for file filtering\nexport const DEFAULT_IGNORE_PATTERNS = [\n 'node_modules/**',\n '**/*.log',\n '.git/**',\n 'dist/**',\n 'build/**',\n 'coverage/**',\n '.DS_Store',\n '*.tmp',\n '*.cache',\n];\n\n// Used by util/storage for directory names\nexport const DEFAULT_DIRECTORY_PREFIX = '.kodrdriv';\n\n// Used by other commands but not exposed in CLI\nexport const INTERNAL_DEFAULT_OUTPUT_FILE = 'output.txt';\n\nexport const INTERNAL_DATETIME_FORMAT = 'YYYY-MM-DD_HH-mm-ss';\n\n// Define defaults in one place\nexport const KODRDRIV_DEFAULTS = {\n dryRun: DEFAULT_DRY_RUN,\n verbose: DEFAULT_VERBOSE,\n debug: DEFAULT_DEBUG,\n overrides: DEFAULT_OVERRIDES,\n model: DEFAULT_MODEL,\n openaiReasoning: DEFAULT_OPENAI_REASONING as 'low' | 'medium' | 'high',\n openaiMaxOutputTokens: DEFAULT_OPENAI_MAX_OUTPUT_TOKENS,\n contextDirectories: DEFAULT_CONTEXT_DIRECTORIES,\n commandName: DEFAULT_COMMAND,\n configDirectory: DEFAULT_CONFIG_DIR,\n outputDirectory: DEFAULT_OUTPUT_DIRECTORY,\n preferencesDirectory: DEFAULT_PREFERENCES_DIRECTORY,\n commit: {\n add: DEFAULT_ADD,\n cached: DEFAULT_CACHED,\n sendit: DEFAULT_SENDIT_MODE,\n interactive: DEFAULT_INTERACTIVE_MODE,\n amend: DEFAULT_AMEND_MODE,\n messageLimit: DEFAULT_MESSAGE_LIMIT,\n skipFileCheck: false,\n maxDiffBytes: DEFAULT_MAX_DIFF_BYTES,\n openaiReasoning: DEFAULT_OPENAI_REASONING as 'low' | 'medium' | 'high',\n openaiMaxOutputTokens: DEFAULT_OPENAI_MAX_OUTPUT_TOKENS,\n },\n release: {\n from: DEFAULT_FROM_COMMIT_ALIAS,\n to: DEFAULT_TO_COMMIT_ALIAS,\n messageLimit: DEFAULT_MESSAGE_LIMIT,\n interactive: DEFAULT_INTERACTIVE_MODE,\n maxDiffBytes: DEFAULT_MAX_DIFF_BYTES,\n noMilestones: false,\n openaiReasoning: DEFAULT_OPENAI_REASONING as 'low' | 'medium' | 'high',\n openaiMaxOutputTokens: DEFAULT_OPENAI_MAX_OUTPUT_TOKENS,\n },\n audioCommit: {\n maxRecordingTime: 300, // 5 minutes default\n audioDevice: undefined, // Auto-detect by default\n openaiReasoning: DEFAULT_OPENAI_REASONING as 'low' | 'medium' | 'high',\n openaiMaxOutputTokens: DEFAULT_OPENAI_MAX_OUTPUT_TOKENS,\n },\n review: {\n includeCommitHistory: true,\n includeRecentDiffs: true,\n includeReleaseNotes: false,\n includeGithubIssues: true,\n commitHistoryLimit: 10,\n diffHistoryLimit: 5,\n releaseNotesLimit: 3,\n githubIssuesLimit: 20,\n sendit: DEFAULT_SENDIT_MODE,\n openaiReasoning: DEFAULT_OPENAI_REASONING as 'low' | 'medium' | 'high',\n openaiMaxOutputTokens: DEFAULT_OPENAI_MAX_OUTPUT_TOKENS,\n },\n audioReview: {\n includeCommitHistory: true,\n includeRecentDiffs: true,\n includeReleaseNotes: false,\n includeGithubIssues: true,\n commitHistoryLimit: 10,\n diffHistoryLimit: 5,\n releaseNotesLimit: 3,\n githubIssuesLimit: 20,\n sendit: DEFAULT_SENDIT_MODE,\n maxRecordingTime: 300, // 5 minutes default\n audioDevice: undefined, // Auto-detect by default\n directory: undefined, // No default directory\n openaiReasoning: DEFAULT_OPENAI_REASONING as 'low' | 'medium' | 'high',\n openaiMaxOutputTokens: DEFAULT_OPENAI_MAX_OUTPUT_TOKENS,\n },\n publish: {\n mergeMethod: DEFAULT_MERGE_METHOD,\n from: DEFAULT_FROM_COMMIT_ALIAS,\n targetVersion: 'patch',\n interactive: DEFAULT_INTERACTIVE_MODE,\n requiredEnvVars: ['GITHUB_TOKEN', 'OPENAI_API_KEY'],\n linkWorkspacePackages: true,\n unlinkWorkspacePackages: true,\n sendit: DEFAULT_SENDIT_MODE,\n targetBranch: 'main',\n noMilestones: false,\n },\n link: {\n scopeRoots: {},\n dryRun: false,\n packageArgument: undefined,\n externals: [],\n },\n unlink: {\n scopeRoots: {},\n workspaceFile: undefined,\n dryRun: false,\n cleanNodeModules: false,\n packageArgument: undefined,\n externals: [],\n },\n tree: {\n directories: undefined,\n exclude: undefined,\n startFrom: undefined,\n stopAt: undefined,\n cmd: undefined,\n\n builtInCommand: undefined,\n continue: false,\n packageArgument: undefined,\n cleanNodeModules: false,\n externals: [],\n },\n development: {\n targetVersion: 'patch',\n noMilestones: false,\n },\n versions: {\n subcommand: undefined,\n directories: undefined,\n },\n excludedPatterns: DEFAULT_EXCLUDED_PATTERNS,\n};\n"],"names":["VERSION","PROGRAM_NAME","DEFAULT_OVERRIDES","DATE_FORMAT_YEAR_MONTH_DAY_HOURS_MINUTES_SECONDS_MILLISECONDS","DEFAULT_VERBOSE","DEFAULT_DRY_RUN","DEFAULT_DEBUG","DEFAULT_MODEL","DEFAULT_OPENAI_REASONING","DEFAULT_OPENAI_MAX_OUTPUT_TOKENS","DEFAULT_OUTPUT_DIRECTORY","DEFAULT_GIT_COMMAND_MAX_BUFFER","DEFAULT_CONTEXT_DIRECTORIES","DEFAULT_CONFIG_DIR","DEFAULT_PREFERENCES_DIRECTORY","path","join","os","homedir","DEFAULT_FROM_COMMIT_ALIAS","DEFAULT_TO_COMMIT_ALIAS","DEFAULT_ADD","DEFAULT_CACHED","DEFAULT_SENDIT_MODE","DEFAULT_INTERACTIVE_MODE","DEFAULT_AMEND_MODE","DEFAULT_MESSAGE_LIMIT","DEFAULT_MAX_DIFF_BYTES","DEFAULT_MERGE_METHOD","DEFAULT_EXCLUDED_PATTERNS","COMMAND_COMMIT","COMMAND_AUDIO_COMMIT","COMMAND_SELECT_AUDIO","COMMAND_RELEASE","COMMAND_REVIEW","COMMAND_AUDIO_REVIEW","COMMAND_PUBLISH","COMMAND_TREE","COMMAND_LINK","COMMAND_UNLINK","COMMAND_CLEAN","COMMAND_DEVELOPMENT","COMMAND_VERSIONS","COMMAND_CHECK_CONFIG","COMMAND_INIT_CONFIG","ALLOWED_COMMANDS","DEFAULT_COMMAND","KODRDRIV_DEFAULTS","dryRun","verbose","debug","overrides","model","openaiReasoning","openaiMaxOutputTokens","contextDirectories","commandName","configDirectory","outputDirectory","preferencesDirectory","commit","add","cached","sendit","interactive","amend","messageLimit","skipFileCheck","maxDiffBytes","release","from","to","noMilestones","audioCommit","maxRecordingTime","audioDevice","undefined","review","includeCommitHistory","includeRecentDiffs","includeReleaseNotes","includeGithubIssues","commitHistoryLimit","diffHistoryLimit","releaseNotesLimit","githubIssuesLimit","audioReview","directory","publish","mergeMethod","targetVersion","requiredEnvVars","linkWorkspacePackages","unlinkWorkspacePackages","targetBranch","link","scopeRoots","packageArgument","externals","unlink","workspaceFile","cleanNodeModules","tree","directories","exclude","startFrom","stopAt","cmd","builtInCommand","continue","development","versions","subcommand","excludedPatterns"],"mappings":"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"}
|
package/dist/content/issues.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { getLogger } from '../logging.js';
|
|
2
2
|
import { getUserChoice as getUserChoice$1 } from '../util/interactive.js';
|
|
3
|
-
import {
|
|
3
|
+
import { createIssue, getOpenIssues } from '../util/github.js';
|
|
4
4
|
import path__default from 'path';
|
|
5
5
|
import os__default from 'os';
|
|
6
6
|
import { spawnSync } from 'child_process';
|
|
@@ -15,8 +15,15 @@
|
|
|
15
15
|
}
|
|
16
16
|
class CommandError extends Error {
|
|
17
17
|
constructor(message, code, recoverable = false, cause){
|
|
18
|
-
super(message), _define_property(this, "code", void 0), _define_property(this, "recoverable", void 0), _define_property(this, "
|
|
18
|
+
super(message), _define_property(this, "code", void 0), _define_property(this, "recoverable", void 0), _define_property(this, "originalCause", void 0);
|
|
19
19
|
this.name = 'CommandError';
|
|
20
|
+
this.code = code;
|
|
21
|
+
this.recoverable = recoverable;
|
|
22
|
+
this.originalCause = cause;
|
|
23
|
+
// Also set the standard cause property for compatibility
|
|
24
|
+
if (cause) {
|
|
25
|
+
this.cause = cause;
|
|
26
|
+
}
|
|
20
27
|
}
|
|
21
28
|
}
|
|
22
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CommandErrors.js","sources":["../../src/error/CommandErrors.ts"],"sourcesContent":["/**\n * Base class for all command-related errors\n */\nexport class CommandError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly recoverable: boolean = false,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'CommandError';\n }\n}\n\n/**\n * Configuration-related errors (missing config, invalid settings, etc.)\n */\nexport class ConfigurationError extends CommandError {\n constructor(message: string, cause?: Error) {\n super(message, 'CONFIG_ERROR', false, cause);\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Validation errors (invalid arguments, missing required data, etc.)\n */\nexport class ValidationError extends CommandError {\n constructor(message: string, cause?: Error) {\n super(message, 'VALIDATION_ERROR', false, cause);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * User cancellation errors (user cancelled operation)\n */\nexport class UserCancellationError extends CommandError {\n constructor(message: string = 'Operation cancelled by user') {\n super(message, 'USER_CANCELLED', true);\n this.name = 'UserCancellationError';\n }\n}\n\n/**\n * External dependency errors (Git, NPM, file system, etc.)\n */\nexport class ExternalDependencyError extends CommandError {\n constructor(message: string, dependency: string, cause?: Error) {\n super(`${dependency}: ${message}`, 'EXTERNAL_DEPENDENCY_ERROR', false, cause);\n this.name = 'ExternalDependencyError';\n }\n}\n\n/**\n * File operation errors (read, write, permissions, etc.)\n */\nexport class FileOperationError extends CommandError {\n constructor(message: string, filePath: string, cause?: Error) {\n super(`File operation failed on ${filePath}: ${message}`, 'FILE_OPERATION_ERROR', false, cause);\n this.name = 'FileOperationError';\n }\n}\n\n/**\n * Pull request check failures with detailed information\n */\nexport class PullRequestCheckError extends CommandError {\n constructor(\n message: string,\n public readonly prNumber: number,\n public readonly failedChecks: Array<{\n name: string;\n conclusion: string;\n detailsUrl?: string;\n summary?: string;\n output?: {\n title?: string;\n summary?: string;\n text?: string;\n };\n }>,\n public readonly prUrl: string,\n public readonly currentBranch?: string\n ) {\n super(message, 'PR_CHECK_FAILED', true);\n this.name = 'PullRequestCheckError';\n }\n\n /**\n * Get specific instructions based on the type of failures\n */\n getRecoveryInstructions(): string[] {\n const instructions: string[] = [];\n const branchName = this.currentBranch || 'your current branch';\n\n // Analyze failure types for specific guidance\n const testFailures = this.failedChecks.filter(check =>\n check.name.toLowerCase().includes('test') ||\n check.name.toLowerCase().includes('ci') ||\n check.output?.title?.toLowerCase().includes('test')\n );\n\n const lintFailures = this.failedChecks.filter(check =>\n check.name.toLowerCase().includes('lint') ||\n check.name.toLowerCase().includes('style') ||\n check.output?.title?.toLowerCase().includes('lint')\n );\n\n const buildFailures = this.failedChecks.filter(check =>\n check.name.toLowerCase().includes('build') ||\n check.name.toLowerCase().includes('compile') ||\n check.output?.title?.toLowerCase().includes('build')\n );\n\n instructions.push('🔧 To fix these failures:');\n instructions.push('');\n\n // Specific instructions based on failure types\n if (testFailures.length > 0) {\n instructions.push('📋 Test Failures:');\n instructions.push(' • Run tests locally: `npm test` or `yarn test`');\n instructions.push(' • Fix failing tests or update test expectations');\n instructions.push(' • Consider running specific test files if identified in the failure details');\n instructions.push('');\n }\n\n if (lintFailures.length > 0) {\n instructions.push('🎨 Linting/Style Failures:');\n instructions.push(' • Run linter locally: `npm run lint` or `yarn lint`');\n instructions.push(' • Auto-fix where possible: `npm run lint:fix` or `yarn lint:fix`');\n instructions.push(' • Check code formatting: `npm run format` or `yarn format`');\n instructions.push('');\n }\n\n if (buildFailures.length > 0) {\n instructions.push('🏗️ Build Failures:');\n instructions.push(' • Run build locally: `npm run build` or `yarn build`');\n instructions.push(' • Check for TypeScript errors: `npx tsc --noEmit`');\n instructions.push(' • Review dependency issues and import paths');\n instructions.push('');\n }\n\n // General workflow instructions\n instructions.push('📤 After fixing the issues:');\n instructions.push(` 1. Stage your changes: \\`git add .\\``);\n instructions.push(` 2. Commit your fixes: \\`git commit -m \"fix: resolve PR check failures\"\\``);\n instructions.push(` 3. Push to ${branchName}: \\`git push origin ${branchName}\\``);\n instructions.push(` 4. The PR checks will automatically re-run`);\n instructions.push('');\n\n instructions.push('🔄 Re-running this command:');\n instructions.push(' • The kodrdriv publish command will automatically detect the existing PR');\n instructions.push(' • Simply run the same command again after pushing your fixes');\n instructions.push(' • You can also manually trigger checks by pushing an empty commit:');\n instructions.push(` \\`git commit --allow-empty -m \"trigger checks\" && git push origin ${branchName}\\``);\n\n return instructions;\n }\n}\n"],"names":["CommandError","Error","message","code","recoverable","cause","name","ValidationError","UserCancellationError","ExternalDependencyError","dependency","FileOperationError","filePath","PullRequestCheckError","getRecoveryInstructions","instructions","branchName","currentBranch","testFailures","failedChecks","filter","check","toLowerCase","includes","output","title","lintFailures","buildFailures","push","length","prNumber","prUrl"],"mappings":"AAAA;;AAEC,IAAA,SAAA,gBAAA,CAAA,GAAA,EAAA,GAAA,EAAA,KAAA,EAAA;;;;;;;;;;;;;AACM,MAAMA,YAAAA,SAAqBC,KAAAA,CAAAA;IAC9B,WAAA,CACIC,OAAe,EACCC,IAAY,EAC5B,WAAgBC,GAAuB,KAAK,EAC5C,KAA6B,CAC/B;AACE,QAAA,KAAK,CAACF,OAAAA,CAAAA,EAAAA,gBAAAA,CAAAA,IAAAA,EAAAA,MAAAA,EAAAA,MAAAA,CAAAA,EAAAA,gBAAAA,CAAAA,IAAAA,EAAAA,aAAAA,EAAAA,MAAAA,CAAAA,EAAAA,gBAAAA,CAAAA,IAAAA,EAAAA,OAAAA,EAAAA,MAAAA,CAAAA,EAAAA,IAAAA,CAJUC,IAAAA,GAAAA,IAAAA,EAAAA,IAAAA,CACAC,WAAAA,GAAAA,kBACAC,KAAAA,GAAAA,KAAAA;QAGhB,IAAI,CAACC,IAAI,GAAG,cAAA;AAChB,IAAA;AACJ;AAYA;;IAGO,MAAMC,eAAAA,SAAwBP,YAAAA,CAAAA;IACjC,WAAA,CAAYE,OAAe,EAAEG,KAAa,CAAE;QACxC,KAAK,CAACH,OAAAA,EAAS,kBAAA,EAAoB,KAAA,EAAOG,KAAAA,CAAAA;QAC1C,IAAI,CAACC,IAAI,GAAG,iBAAA;AAChB,IAAA;AACJ;AAEA;;IAGO,MAAME,qBAAAA,SAA8BR,YAAAA,CAAAA;IACvC,WAAA,CAAYE,OAAAA,GAAkB,6BAA6B,CAAE;QACzD,KAAK,CAACA,SAAS,gBAAA,EAAkB,IAAA,CAAA;QACjC,IAAI,CAACI,IAAI,GAAG,uBAAA;AAChB,IAAA;AACJ;AAEA;;IAGO,MAAMG,uBAAAA,SAAgCT,YAAAA,CAAAA;AACzC,IAAA,WAAA,CAAYE,OAAe,EAAEQ,UAAkB,EAAEL,KAAa,CAAE;QAC5D,KAAK,CAAC,GAAGK,UAAAA,CAAW,EAAE,EAAER,OAAAA,CAAAA,CAAS,EAAE,6BAA6B,KAAA,EAAOG,KAAAA,CAAAA;QACvE,IAAI,CAACC,IAAI,GAAG,yBAAA;AAChB,IAAA;AACJ;AAEA;;IAGO,MAAMK,kBAAAA,SAA2BX,YAAAA,CAAAA;AACpC,IAAA,WAAA,CAAYE,OAAe,EAAEU,QAAgB,EAAEP,KAAa,CAAE;QAC1D,KAAK,CAAC,CAAC,yBAAyB,EAAEO,QAAAA,CAAS,EAAE,EAAEV,OAAAA,CAAAA,CAAS,EAAE,sBAAA,EAAwB,KAAA,EAAOG,KAAAA,CAAAA;QACzF,IAAI,CAACC,IAAI,GAAG,oBAAA;AAChB,IAAA;AACJ;AAEA;;IAGO,MAAMO,qBAAAA,SAA8Bb,YAAAA,CAAAA;AAsBvC;;AAEC,QACDc,uBAAAA,GAAoC;AAChC,QAAA,MAAMC,eAAyB,EAAE;AACjC,QAAA,MAAMC,UAAAA,GAAa,IAAI,CAACC,aAAa,IAAI,qBAAA;;AAGzC,QAAA,MAAMC,eAAe,IAAI,CAACC,YAAY,CAACC,MAAM,CAACC,CAAAA,KAAAA,GAAAA;gBAG1CA,mBAAAA,EAAAA,aAAAA;AAFAA,YAAAA,OAAAA,KAAAA,CAAMf,IAAI,CAACgB,WAAW,EAAA,CAAGC,QAAQ,CAAC,MAAA,CAAA,IAClCF,KAAAA,CAAMf,IAAI,CAACgB,WAAW,EAAA,CAAGC,QAAQ,CAAC,IAAA,CAAA,KAAA,CAClCF,aAAAA,GAAAA,KAAAA,CAAMG,MAAM,MAAA,IAAA,IAAZH,aAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,CAAAA,mBAAAA,GAAAA,aAAAA,CAAcI,KAAK,MAAA,IAAA,IAAnBJ,mBAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,mBAAAA,CAAqBC,WAAW,EAAA,CAAGC,QAAQ,CAAC,MAAA,CAAA,CAAA;;AAGhD,QAAA,MAAMG,eAAe,IAAI,CAACP,YAAY,CAACC,MAAM,CAACC,CAAAA,KAAAA,GAAAA;gBAG1CA,mBAAAA,EAAAA,aAAAA;AAFAA,YAAAA,OAAAA,KAAAA,CAAMf,IAAI,CAACgB,WAAW,EAAA,CAAGC,QAAQ,CAAC,MAAA,CAAA,IAClCF,KAAAA,CAAMf,IAAI,CAACgB,WAAW,EAAA,CAAGC,QAAQ,CAAC,OAAA,CAAA,KAAA,CAClCF,aAAAA,GAAAA,KAAAA,CAAMG,MAAM,MAAA,IAAA,IAAZH,aAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,CAAAA,mBAAAA,GAAAA,aAAAA,CAAcI,KAAK,MAAA,IAAA,IAAnBJ,mBAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,mBAAAA,CAAqBC,WAAW,EAAA,CAAGC,QAAQ,CAAC,MAAA,CAAA,CAAA;;AAGhD,QAAA,MAAMI,gBAAgB,IAAI,CAACR,YAAY,CAACC,MAAM,CAACC,CAAAA,KAAAA,GAAAA;gBAG3CA,mBAAAA,EAAAA,aAAAA;AAFAA,YAAAA,OAAAA,KAAAA,CAAMf,IAAI,CAACgB,WAAW,EAAA,CAAGC,QAAQ,CAAC,OAAA,CAAA,IAClCF,KAAAA,CAAMf,IAAI,CAACgB,WAAW,EAAA,CAAGC,QAAQ,CAAC,SAAA,CAAA,KAAA,CAClCF,aAAAA,GAAAA,KAAAA,CAAMG,MAAM,MAAA,IAAA,IAAZH,aAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,CAAAA,mBAAAA,GAAAA,aAAAA,CAAcI,KAAK,MAAA,IAAA,IAAnBJ,mBAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,mBAAAA,CAAqBC,WAAW,EAAA,CAAGC,QAAQ,CAAC,OAAA,CAAA,CAAA;;AAGhDR,QAAAA,YAAAA,CAAaa,IAAI,CAAC,2BAAA,CAAA;AAClBb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,EAAA,CAAA;;QAGlB,IAAIV,YAAAA,CAAaW,MAAM,GAAG,CAAA,EAAG;AACzBd,YAAAA,YAAAA,CAAaa,IAAI,CAAC,mBAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,mDAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,oDAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,gFAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,EAAA,CAAA;AACtB,QAAA;QAEA,IAAIF,YAAAA,CAAaG,MAAM,GAAG,CAAA,EAAG;AACzBd,YAAAA,YAAAA,CAAaa,IAAI,CAAC,4BAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,wDAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,qEAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,+DAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,EAAA,CAAA;AACtB,QAAA;QAEA,IAAID,aAAAA,CAAcE,MAAM,GAAG,CAAA,EAAG;AAC1Bd,YAAAA,YAAAA,CAAaa,IAAI,CAAC,qBAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,yDAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,sDAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,gDAAA,CAAA;AAClBb,YAAAA,YAAAA,CAAaa,IAAI,CAAC,EAAA,CAAA;AACtB,QAAA;;AAGAb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,6BAAA,CAAA;AAClBb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,CAAC,uCAAuC,CAAC,CAAA;AAC3Db,QAAAA,YAAAA,CAAaa,IAAI,CAAC,CAAC,2EAA2E,CAAC,CAAA;QAC/Fb,YAAAA,CAAaa,IAAI,CAAC,CAAC,cAAc,EAAEZ,WAAW,oBAAoB,EAAEA,UAAAA,CAAW,EAAE,CAAC,CAAA;AAClFD,QAAAA,YAAAA,CAAaa,IAAI,CAAC,CAAC,6CAA6C,CAAC,CAAA;AACjEb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,EAAA,CAAA;AAElBb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,6BAAA,CAAA;AAClBb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,6EAAA,CAAA;AAClBb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,iEAAA,CAAA;AAClBb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,uEAAA,CAAA;AAClBb,QAAAA,YAAAA,CAAaa,IAAI,CAAC,CAAC,uEAAuE,EAAEZ,UAAAA,CAAW,EAAE,CAAC,CAAA;QAE1G,OAAOD,YAAAA;AACX,IAAA;AA1FA,IAAA,WAAA,CACIb,OAAe,EACf,QAAgC,EAChBiB,YAUd,EACF,KAA6B,EACbF,aAAsB,CACxC;QACE,KAAK,CAACf,OAAAA,EAAS,iBAAA,EAAmB,IAAA,CAAA,EAAA,gBAAA,CAAA,IAAA,EAAA,UAAA,EAAA,MAAA,CAAA,EAAA,gBAAA,CAAA,IAAA,EAAA,cAAA,EAAA,MAAA,CAAA,EAAA,gBAAA,CAAA,IAAA,EAAA,OAAA,EAAA,MAAA,CAAA,EAAA,gBAAA,CAAA,IAAA,EAAA,eAAA,EAAA,MAAA,CAAA,EAAA,IAAA,CAflB4B,QAAAA,GAAAA,eACAX,YAAAA,GAAAA,YAAAA,EAAAA,IAAAA,CAWAY,KAAAA,GAAAA,KAAAA,EAAAA,IAAAA,CACAd,aAAAA,GAAAA,aAAAA;QAGhB,IAAI,CAACX,IAAI,GAAG,uBAAA;AAChB,IAAA;AAwEJ;;;;"}
|
|
1
|
+
{"version":3,"file":"CommandErrors.js","sources":["../../src/error/CommandErrors.ts"],"sourcesContent":["/**\n * Base class for all command-related errors\n */\nexport class CommandError extends Error {\n public readonly code: string;\n public readonly recoverable: boolean;\n public readonly originalCause?: Error;\n\n constructor(\n message: string,\n code: string,\n recoverable: boolean = false,\n cause?: Error\n ) {\n super(message);\n this.name = 'CommandError';\n this.code = code;\n this.recoverable = recoverable;\n this.originalCause = cause;\n // Also set the standard cause property for compatibility\n if (cause) {\n (this as any).cause = cause;\n }\n }\n}\n\n/**\n * Configuration-related errors (missing config, invalid settings, etc.)\n */\nexport class ConfigurationError extends CommandError {\n constructor(message: string, cause?: Error) {\n super(message, 'CONFIG_ERROR', false, cause);\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Validation errors (invalid arguments, missing required data, etc.)\n */\nexport class ValidationError extends CommandError {\n constructor(message: string, cause?: Error) {\n super(message, 'VALIDATION_ERROR', false, cause);\n this.name = 'ValidationError';\n }\n}\n\n/**\n * User cancellation errors (user cancelled operation)\n */\nexport class UserCancellationError extends CommandError {\n constructor(message: string = 'Operation cancelled by user') {\n super(message, 'USER_CANCELLED', true);\n this.name = 'UserCancellationError';\n }\n}\n\n/**\n * External dependency errors (Git, NPM, file system, etc.)\n */\nexport class ExternalDependencyError extends CommandError {\n constructor(message: string, dependency: string, cause?: Error) {\n super(`${dependency}: ${message}`, 'EXTERNAL_DEPENDENCY_ERROR', false, cause);\n this.name = 'ExternalDependencyError';\n }\n}\n\n/**\n * File operation errors (read, write, permissions, etc.)\n */\nexport class FileOperationError extends CommandError {\n constructor(message: string, filePath: string, cause?: Error) {\n super(`File operation failed on ${filePath}: ${message}`, 'FILE_OPERATION_ERROR', false, cause);\n this.name = 'FileOperationError';\n }\n}\n\n/**\n * Pull request check failures with detailed information\n */\nexport class PullRequestCheckError extends CommandError {\n constructor(\n message: string,\n public readonly prNumber: number,\n public readonly failedChecks: Array<{\n name: string;\n conclusion: string;\n detailsUrl?: string;\n summary?: string;\n output?: {\n title?: string;\n summary?: string;\n text?: string;\n };\n }>,\n public readonly prUrl: string,\n public readonly currentBranch?: string\n ) {\n super(message, 'PR_CHECK_FAILED', true);\n this.name = 'PullRequestCheckError';\n }\n\n /**\n * Get specific instructions based on the type of failures\n */\n getRecoveryInstructions(): string[] {\n const instructions: string[] = [];\n const branchName = this.currentBranch || 'your current branch';\n\n // Analyze failure types for specific guidance\n const testFailures = this.failedChecks.filter(check =>\n check.name.toLowerCase().includes('test') ||\n check.name.toLowerCase().includes('ci') ||\n check.output?.title?.toLowerCase().includes('test')\n );\n\n const lintFailures = this.failedChecks.filter(check =>\n check.name.toLowerCase().includes('lint') ||\n check.name.toLowerCase().includes('style') ||\n check.output?.title?.toLowerCase().includes('lint')\n );\n\n const buildFailures = this.failedChecks.filter(check =>\n check.name.toLowerCase().includes('build') ||\n check.name.toLowerCase().includes('compile') ||\n check.output?.title?.toLowerCase().includes('build')\n );\n\n instructions.push('🔧 To fix these failures:');\n instructions.push('');\n\n // Specific instructions based on failure types\n if (testFailures.length > 0) {\n instructions.push('📋 Test Failures:');\n instructions.push(' • Run tests locally: `npm test` or `yarn test`');\n instructions.push(' • Fix failing tests or update test expectations');\n instructions.push(' • Consider running specific test files if identified in the failure details');\n instructions.push('');\n }\n\n if (lintFailures.length > 0) {\n instructions.push('🎨 Linting/Style Failures:');\n instructions.push(' • Run linter locally: `npm run lint` or `yarn lint`');\n instructions.push(' • Auto-fix where possible: `npm run lint:fix` or `yarn lint:fix`');\n instructions.push(' • Check code formatting: `npm run format` or `yarn format`');\n instructions.push('');\n }\n\n if (buildFailures.length > 0) {\n instructions.push('🏗️ Build Failures:');\n instructions.push(' • Run build locally: `npm run build` or `yarn build`');\n instructions.push(' • Check for TypeScript errors: `npx tsc --noEmit`');\n instructions.push(' • Review dependency issues and import paths');\n instructions.push('');\n }\n\n // General workflow instructions\n instructions.push('📤 After fixing the issues:');\n instructions.push(` 1. Stage your changes: \\`git add .\\``);\n instructions.push(` 2. Commit your fixes: \\`git commit -m \"fix: resolve PR check failures\"\\``);\n instructions.push(` 3. Push to ${branchName}: \\`git push origin ${branchName}\\``);\n instructions.push(` 4. The PR checks will automatically re-run`);\n instructions.push('');\n\n instructions.push('🔄 Re-running this command:');\n instructions.push(' • The kodrdriv publish command will automatically detect the existing PR');\n instructions.push(' • Simply run the same command again after pushing your fixes');\n instructions.push(' • You can also manually trigger checks by pushing an empty commit:');\n instructions.push(` \\`git commit --allow-empty -m \"trigger checks\" && git push origin ${branchName}\\``);\n\n return instructions;\n }\n}\n"],"names":["CommandError","Error","message","code","recoverable","cause","originalCause","name","ValidationError","UserCancellationError","ExternalDependencyError","dependency","FileOperationError","filePath","PullRequestCheckError","getRecoveryInstructions","instructions","branchName","currentBranch","testFailures","failedChecks","filter","check","toLowerCase","includes","output","title","lintFailures","buildFailures","push","length","prNumber","prUrl"],"mappings":"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"}
|
package/dist/prompt/commit.js
CHANGED
|
@@ -19,6 +19,12 @@ const __dirname = path__default.dirname(__filename);
|
|
|
19
19
|
// Build content items for the prompt
|
|
20
20
|
const contentItems = [];
|
|
21
21
|
const contextItems = [];
|
|
22
|
+
// Developer Note: Direction is injected first as the highest-priority prompt input
|
|
23
|
+
// This ensures user guidance takes precedence over other context sources like
|
|
24
|
+
// GitHub issues or commit history. Direction content is sanitized via sanitizeDirection()
|
|
25
|
+
// to prevent template breakage (newlines converted to spaces, whitespace normalized,
|
|
26
|
+
// length limited to 2000 chars). See tests/util/validation.test.ts for sanitization behavior
|
|
27
|
+
// and src/commands/commit.ts line 446 for debug logging of direction processing.
|
|
22
28
|
if (userDirection) {
|
|
23
29
|
contentItems.push({
|
|
24
30
|
content: userDirection,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commit.js","sources":["../../src/prompt/commit.ts"],"sourcesContent":["import { Prompt, recipe } from '@riotprompt/riotprompt';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Types for the commit prompt\nexport type Content = {\n diffContent: string;\n userDirection?: string;\n isFileContent?: boolean; // Flag to indicate if diffContent is actually file content\n githubIssuesContext?: string; // GitHub issues related to current version/milestone\n};\n\nexport type Context = {\n logContext?: string;\n context?: string;\n directories?: string[];\n};\n\nexport type Config = {\n overridePaths?: string[];\n overrides?: boolean;\n}\n\n/**\n * Build a commit prompt using RiotPrompt Recipes.\n *\n * This prompt is configured to generate multiline commit messages by default,\n * with separate lines/bullet points for different groups of changes rather\n * than squeezing everything into single lines.\n *\n * @param runConfig The runtime configuration provided by the CLI\n * @param content Mandatory content inputs (e.g. diff)\n * @param ctx Optional contextual inputs configured by the user\n */\nexport const createPrompt = async (\n { overridePaths: _overridePaths, overrides: _overrides }: Config,\n { diffContent, userDirection, isFileContent, githubIssuesContext }: Content,\n { logContext, context, directories }: Context = {}\n): Promise<Prompt> => {\n const basePath = __dirname;\n\n // Build content items for the prompt\n const contentItems = [];\n const contextItems = [];\n\n if (userDirection) {\n contentItems.push({ content: userDirection, title: 'User Direction' });\n }\n if (diffContent) {\n const contentTitle = isFileContent ? 'Project Files' : 'Diff';\n contentItems.push({ content: diffContent, title: contentTitle });\n }\n if (githubIssuesContext) {\n contentItems.push({ content: githubIssuesContext, title: 'Recent GitHub Issues' });\n }\n\n if (logContext) {\n contextItems.push({ content: logContext, title: 'Log Context' });\n }\n if (context) {\n contextItems.push({ content: context, title: 'User Context' });\n }\n if (directories && directories.length > 0) {\n contextItems.push({ directories, title: 'Directories' });\n }\n\n return recipe(basePath)\n .persona({ path: 'personas/you.md' })\n .instructions({ path: 'instructions/commit.md' })\n .overridePaths(_overridePaths ?? [])\n .overrides(_overrides ?? true)\n .content(...contentItems)\n .context(...contextItems)\n .cook();\n};\n"],"names":["__filename","fileURLToPath","url","__dirname","path","dirname","createPrompt","overridePaths","_overridePaths","overrides","_overrides","diffContent","userDirection","isFileContent","githubIssuesContext","logContext","context","directories","basePath","contentItems","contextItems","push","content","title","contentTitle","length","recipe","persona","instructions","cook"],"mappings":";;;;AAIA,MAAMA,UAAAA,GAAaC,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAYC,GAAG,CAAA;AAChD,MAAMC,SAAAA,GAAYC,aAAAA,CAAKC,OAAO,CAACL,UAAAA,CAAAA;AAqB/B;;;;;;;;;;AAUC,IACM,MAAMM,YAAAA,GAAe,OACxB,EAAEC,aAAAA,EAAeC,cAAc,EAAEC,SAAAA,EAAWC,UAAU,EAAU,EAChE,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,mBAAmB,EAAW,EAC3E,EAAEC,UAAU,EAAEC,OAAO,EAAEC,WAAW,EAAW,GAAG,EAAE,GAAA;AAElD,IAAA,MAAMC,QAAAA,GAAWf,SAAAA;;AAGjB,IAAA,MAAMgB,eAAe,EAAE;AACvB,IAAA,MAAMC,eAAe,EAAE
|
|
1
|
+
{"version":3,"file":"commit.js","sources":["../../src/prompt/commit.ts"],"sourcesContent":["import { Prompt, recipe } from '@riotprompt/riotprompt';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// Types for the commit prompt\nexport type Content = {\n diffContent: string;\n userDirection?: string;\n isFileContent?: boolean; // Flag to indicate if diffContent is actually file content\n githubIssuesContext?: string; // GitHub issues related to current version/milestone\n};\n\nexport type Context = {\n logContext?: string;\n context?: string;\n directories?: string[];\n};\n\nexport type Config = {\n overridePaths?: string[];\n overrides?: boolean;\n}\n\n/**\n * Build a commit prompt using RiotPrompt Recipes.\n *\n * This prompt is configured to generate multiline commit messages by default,\n * with separate lines/bullet points for different groups of changes rather\n * than squeezing everything into single lines.\n *\n * @param runConfig The runtime configuration provided by the CLI\n * @param content Mandatory content inputs (e.g. diff)\n * @param ctx Optional contextual inputs configured by the user\n */\nexport const createPrompt = async (\n { overridePaths: _overridePaths, overrides: _overrides }: Config,\n { diffContent, userDirection, isFileContent, githubIssuesContext }: Content,\n { logContext, context, directories }: Context = {}\n): Promise<Prompt> => {\n const basePath = __dirname;\n\n // Build content items for the prompt\n const contentItems = [];\n const contextItems = [];\n\n // Developer Note: Direction is injected first as the highest-priority prompt input\n // This ensures user guidance takes precedence over other context sources like\n // GitHub issues or commit history. Direction content is sanitized via sanitizeDirection()\n // to prevent template breakage (newlines converted to spaces, whitespace normalized,\n // length limited to 2000 chars). See tests/util/validation.test.ts for sanitization behavior\n // and src/commands/commit.ts line 446 for debug logging of direction processing.\n if (userDirection) {\n contentItems.push({ content: userDirection, title: 'User Direction' });\n }\n if (diffContent) {\n const contentTitle = isFileContent ? 'Project Files' : 'Diff';\n contentItems.push({ content: diffContent, title: contentTitle });\n }\n if (githubIssuesContext) {\n contentItems.push({ content: githubIssuesContext, title: 'Recent GitHub Issues' });\n }\n\n if (logContext) {\n contextItems.push({ content: logContext, title: 'Log Context' });\n }\n if (context) {\n contextItems.push({ content: context, title: 'User Context' });\n }\n if (directories && directories.length > 0) {\n contextItems.push({ directories, title: 'Directories' });\n }\n\n return recipe(basePath)\n .persona({ path: 'personas/you.md' })\n .instructions({ path: 'instructions/commit.md' })\n .overridePaths(_overridePaths ?? [])\n .overrides(_overrides ?? true)\n .content(...contentItems)\n .context(...contextItems)\n .cook();\n};\n"],"names":["__filename","fileURLToPath","url","__dirname","path","dirname","createPrompt","overridePaths","_overridePaths","overrides","_overrides","diffContent","userDirection","isFileContent","githubIssuesContext","logContext","context","directories","basePath","contentItems","contextItems","push","content","title","contentTitle","length","recipe","persona","instructions","cook"],"mappings":";;;;AAIA,MAAMA,UAAAA,GAAaC,aAAAA,CAAc,MAAA,CAAA,IAAA,CAAYC,GAAG,CAAA;AAChD,MAAMC,SAAAA,GAAYC,aAAAA,CAAKC,OAAO,CAACL,UAAAA,CAAAA;AAqB/B;;;;;;;;;;AAUC,IACM,MAAMM,YAAAA,GAAe,OACxB,EAAEC,aAAAA,EAAeC,cAAc,EAAEC,SAAAA,EAAWC,UAAU,EAAU,EAChE,EAAEC,WAAW,EAAEC,aAAa,EAAEC,aAAa,EAAEC,mBAAmB,EAAW,EAC3E,EAAEC,UAAU,EAAEC,OAAO,EAAEC,WAAW,EAAW,GAAG,EAAE,GAAA;AAElD,IAAA,MAAMC,QAAAA,GAAWf,SAAAA;;AAGjB,IAAA,MAAMgB,eAAe,EAAE;AACvB,IAAA,MAAMC,eAAe,EAAE;;;;;;;AAQvB,IAAA,IAAIR,aAAAA,EAAe;AACfO,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASV,aAAAA;YAAeW,KAAAA,EAAO;AAAiB,SAAA,CAAA;AACxE,IAAA;AACA,IAAA,IAAIZ,WAAAA,EAAa;QACb,MAAMa,YAAAA,GAAeX,gBAAgB,eAAA,GAAkB,MAAA;AACvDM,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASX,WAAAA;YAAaY,KAAAA,EAAOC;AAAa,SAAA,CAAA;AAClE,IAAA;AACA,IAAA,IAAIV,mBAAAA,EAAqB;AACrBK,QAAAA,YAAAA,CAAaE,IAAI,CAAC;YAAEC,OAAAA,EAASR,mBAAAA;YAAqBS,KAAAA,EAAO;AAAuB,SAAA,CAAA;AACpF,IAAA;AAEA,IAAA,IAAIR,UAAAA,EAAY;AACZK,QAAAA,YAAAA,CAAaC,IAAI,CAAC;YAAEC,OAAAA,EAASP,UAAAA;YAAYQ,KAAAA,EAAO;AAAc,SAAA,CAAA;AAClE,IAAA;AACA,IAAA,IAAIP,OAAAA,EAAS;AACTI,QAAAA,YAAAA,CAAaC,IAAI,CAAC;YAAEC,OAAAA,EAASN,OAAAA;YAASO,KAAAA,EAAO;AAAe,SAAA,CAAA;AAChE,IAAA;AACA,IAAA,IAAIN,WAAAA,IAAeA,WAAAA,CAAYQ,MAAM,GAAG,CAAA,EAAG;AACvCL,QAAAA,YAAAA,CAAaC,IAAI,CAAC;AAAEJ,YAAAA,WAAAA;YAAaM,KAAAA,EAAO;AAAc,SAAA,CAAA;AAC1D,IAAA;IAEA,OAAOG,MAAAA,CAAOR,QAAAA,CAAAA,CACTS,OAAO,CAAC;QAAEvB,IAAAA,EAAM;AAAkB,KAAA,CAAA,CAClCwB,YAAY,CAAC;QAAExB,IAAAA,EAAM;AAAyB,KAAA,CAAA,CAC9CG,aAAa,CAACC,cAAAA,KAAAA,IAAAA,IAAAA,4BAAAA,cAAAA,GAAkB,EAAE,EAClCC,SAAS,CAACC,uBAAAA,UAAAA,KAAAA,MAAAA,GAAAA,UAAAA,GAAc,MACxBY,OAAO,CAAA,GAAIH,cACXH,OAAO,CAAA,GAAII,cACXS,IAAI,EAAA;AACb;;;;"}
|
|
@@ -20,7 +20,7 @@ Respond with valid JSON in this exact format:
|
|
|
20
20
|
"totalIssues": number,
|
|
21
21
|
"issues": [
|
|
22
22
|
{
|
|
23
|
-
"title": "
|
|
23
|
+
"title": "Short, clear title (4-8 words max)",
|
|
24
24
|
"description": "Comprehensive, prompt-ready description that serves as a detailed coding instruction",
|
|
25
25
|
"priority": "low|medium|high",
|
|
26
26
|
"category": "ui|content|functionality|security|accessibility|performance|investigation|other",
|
|
@@ -48,8 +48,16 @@ Include a category explicitly for exploration:
|
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
51
|
-
## 🎯 **Writing
|
|
51
|
+
## 🎯 **Writing Issue Titles and Descriptions**
|
|
52
52
|
|
|
53
|
+
### **Issue Title Guidelines:**
|
|
54
|
+
- **Keep titles short and readable:** Aim for 3-6 words maximum
|
|
55
|
+
- **Use clear, simple language:** Avoid technical jargon in titles
|
|
56
|
+
- **Be specific but concise:** "Fix login timeout" not "Implement comprehensive authentication flow timeout handling"
|
|
57
|
+
- **Focus on the core problem:** "Add error logging" not "Enhance system robustness through comprehensive error logging"
|
|
58
|
+
- **Make titles scannable:** Developers should quickly understand the issue from the title alone
|
|
59
|
+
|
|
60
|
+
### **Issue Description Guidelines:**
|
|
53
61
|
Issue descriptions should be comprehensive, detailed instructions that could be directly used as prompts for AI coding assistants like GitHub Copilot or Cursor. Think of each description as a complete coding task specification:
|
|
54
62
|
|
|
55
63
|
### **Description Structure:**
|
|
@@ -115,6 +123,7 @@ Consider how issues relate to each other and identify dependencies or groupings:
|
|
|
115
123
|
|
|
116
124
|
## ✅ **DO:**
|
|
117
125
|
|
|
126
|
+
- **Write short, readable titles** (3-6 words) that clearly communicate the issue
|
|
118
127
|
- **Write detailed, prompt-ready descriptions** that could be handed directly to a coding assistant
|
|
119
128
|
- **Include specific file paths, function names, and implementation details** when relevant
|
|
120
129
|
- **Capture subtle or implicit feedback** as actionable investigative tasks
|
|
@@ -126,6 +135,7 @@ Consider how issues relate to each other and identify dependencies or groupings:
|
|
|
126
135
|
|
|
127
136
|
## ❌ **DO NOT:**
|
|
128
137
|
|
|
138
|
+
- **Write wordy or technical titles** like "Implement comprehensive authentication flow timeout handling" or "Enhance system robustness through comprehensive error logging"
|
|
129
139
|
- **Write generic or vague descriptions** like "improve error handling" or "fix the UI"
|
|
130
140
|
- **Skip implementation details** when you have enough context to provide them
|
|
131
141
|
- **Ignore issue relationships** - always consider how issues might interact
|
|
@@ -156,4 +166,4 @@ Consider how issues relate to each other and identify dependencies or groupings:
|
|
|
156
166
|
|
|
157
167
|
---
|
|
158
168
|
|
|
159
|
-
**Your goal** is to comprehensively transform the reviewer's observations, comments, and implicit ideas into clearly defined, prompt-ready issues that serve as detailed coding instructions. Each issue should
|
|
169
|
+
**Your goal** is to comprehensively transform the reviewer's observations, comments, and implicit ideas into clearly defined, prompt-ready issues that serve as detailed coding instructions. Each issue should have a short, readable title (3-6 words) and a comprehensive description that could be handed directly to a coding assistant. Consider relationships and dependencies between multiple issues. Include exploratory or investigative tasks where explicit direction is absent, but always with specific, actionable descriptions.
|
package/dist/util/openai.js
CHANGED
|
@@ -41,6 +41,54 @@ function _define_property(obj, key, value) {
|
|
|
41
41
|
// Return command-specific model if available, otherwise global model
|
|
42
42
|
return commandModel || config.model || 'gpt-4o-mini';
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Get the appropriate OpenAI reasoning level based on command-specific configuration
|
|
46
|
+
* Command-specific reasoning overrides the global reasoning setting
|
|
47
|
+
*/ function getOpenAIReasoningForCommand(config, commandName) {
|
|
48
|
+
let commandReasoning;
|
|
49
|
+
switch(commandName){
|
|
50
|
+
case 'commit':
|
|
51
|
+
case 'audio-commit':
|
|
52
|
+
var _config_commit;
|
|
53
|
+
commandReasoning = (_config_commit = config.commit) === null || _config_commit === void 0 ? void 0 : _config_commit.openaiReasoning;
|
|
54
|
+
break;
|
|
55
|
+
case 'release':
|
|
56
|
+
var _config_release;
|
|
57
|
+
commandReasoning = (_config_release = config.release) === null || _config_release === void 0 ? void 0 : _config_release.openaiReasoning;
|
|
58
|
+
break;
|
|
59
|
+
case 'review':
|
|
60
|
+
case 'audio-review':
|
|
61
|
+
var _config_review;
|
|
62
|
+
commandReasoning = (_config_review = config.review) === null || _config_review === void 0 ? void 0 : _config_review.openaiReasoning;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
// Return command-specific reasoning if available, otherwise global reasoning
|
|
66
|
+
return commandReasoning || config.openaiReasoning || 'low';
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get the appropriate OpenAI max output tokens based on command-specific configuration
|
|
70
|
+
* Command-specific max output tokens overrides the global setting
|
|
71
|
+
*/ function getOpenAIMaxOutputTokensForCommand(config, commandName) {
|
|
72
|
+
let commandMaxOutputTokens;
|
|
73
|
+
switch(commandName){
|
|
74
|
+
case 'commit':
|
|
75
|
+
case 'audio-commit':
|
|
76
|
+
var _config_commit;
|
|
77
|
+
commandMaxOutputTokens = (_config_commit = config.commit) === null || _config_commit === void 0 ? void 0 : _config_commit.openaiMaxOutputTokens;
|
|
78
|
+
break;
|
|
79
|
+
case 'release':
|
|
80
|
+
var _config_release;
|
|
81
|
+
commandMaxOutputTokens = (_config_release = config.release) === null || _config_release === void 0 ? void 0 : _config_release.openaiMaxOutputTokens;
|
|
82
|
+
break;
|
|
83
|
+
case 'review':
|
|
84
|
+
case 'audio-review':
|
|
85
|
+
var _config_review;
|
|
86
|
+
commandMaxOutputTokens = (_config_review = config.review) === null || _config_review === void 0 ? void 0 : _config_review.openaiMaxOutputTokens;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
// Return command-specific max output tokens if available, otherwise global setting
|
|
90
|
+
return commandMaxOutputTokens || config.openaiMaxOutputTokens || 10000;
|
|
91
|
+
}
|
|
44
92
|
class OpenAIError extends Error {
|
|
45
93
|
constructor(message, isTokenLimitError = false){
|
|
46
94
|
super(message), _define_property(this, "isTokenLimitError", void 0), this.isTokenLimitError = isTokenLimitError;
|
|
@@ -60,8 +108,12 @@ function isRateLimitError(error) {
|
|
|
60
108
|
if (error.status === 429 || error.code === 'rate_limit_exceeded') {
|
|
61
109
|
return true;
|
|
62
110
|
}
|
|
63
|
-
|
|
64
|
-
|
|
111
|
+
// Only check message if it exists
|
|
112
|
+
if (error.message) {
|
|
113
|
+
const message = error.message.toLowerCase();
|
|
114
|
+
return message.includes('rate limit exceeded') || message.includes('too many requests') || message.includes('quota exceeded') || message.includes('rate') && message.includes('limit');
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
65
117
|
}
|
|
66
118
|
async function createCompletion(messages, options = {
|
|
67
119
|
model: "gpt-4o-mini"
|
|
@@ -86,27 +138,36 @@ async function createCompletion(messages, options = {
|
|
|
86
138
|
const modelToUse = options.model || "gpt-4o-mini";
|
|
87
139
|
logger.info('🤖 Making request to OpenAI using model: %s', modelToUse);
|
|
88
140
|
logger.debug('Sending prompt to OpenAI: %j', messages);
|
|
89
|
-
|
|
90
|
-
|
|
141
|
+
var _options_openaiMaxOutputTokens, _ref;
|
|
142
|
+
// Use openaiMaxOutputTokens if specified (highest priority), otherwise fall back to maxTokens, or default to 10000
|
|
143
|
+
const maxCompletionTokens = (_ref = (_options_openaiMaxOutputTokens = options.openaiMaxOutputTokens) !== null && _options_openaiMaxOutputTokens !== void 0 ? _options_openaiMaxOutputTokens : options.maxTokens) !== null && _ref !== void 0 ? _ref : 10000;
|
|
91
144
|
// Save request debug file if enabled
|
|
92
145
|
if (options.debug && (options.debugRequestFile || options.debugFile)) {
|
|
93
146
|
const requestData = {
|
|
94
147
|
model: modelToUse,
|
|
95
148
|
messages,
|
|
96
149
|
max_completion_tokens: maxCompletionTokens,
|
|
97
|
-
response_format: options.responseFormat
|
|
150
|
+
response_format: options.responseFormat,
|
|
151
|
+
reasoning_effort: options.openaiReasoning
|
|
98
152
|
};
|
|
99
153
|
const debugFile = options.debugRequestFile || options.debugFile;
|
|
100
154
|
await storage.writeFile(debugFile, JSON.stringify(requestData, null, 2), 'utf8');
|
|
101
155
|
logger.debug('Wrote request debug file to %s', debugFile);
|
|
102
156
|
}
|
|
103
|
-
//
|
|
104
|
-
const
|
|
157
|
+
// Prepare the API call options
|
|
158
|
+
const apiOptions = {
|
|
105
159
|
model: modelToUse,
|
|
106
160
|
messages,
|
|
107
161
|
max_completion_tokens: maxCompletionTokens,
|
|
108
162
|
response_format: options.responseFormat
|
|
109
|
-
}
|
|
163
|
+
};
|
|
164
|
+
// Add reasoning parameter if specified and model supports it
|
|
165
|
+
if (options.openaiReasoning && (modelToUse.includes('gpt-5') || modelToUse.includes('o3'))) {
|
|
166
|
+
apiOptions.reasoning_effort = options.openaiReasoning;
|
|
167
|
+
logger.debug('Using OpenAI reasoning level: %s', options.openaiReasoning);
|
|
168
|
+
}
|
|
169
|
+
// Add timeout wrapper to the OpenAI API call
|
|
170
|
+
const completionPromise = openai.chat.completions.create(apiOptions);
|
|
110
171
|
// Create timeout promise with proper cleanup to prevent memory leaks
|
|
111
172
|
let timeoutId = null;
|
|
112
173
|
const timeoutPromise = new Promise((_, reject)=>{
|
|
@@ -280,5 +341,5 @@ async function transcribeAudio(filePath, options = {
|
|
|
280
341
|
}
|
|
281
342
|
}
|
|
282
343
|
|
|
283
|
-
export { OpenAIError, createCompletion, createCompletionWithRetry, getModelForCommand, isRateLimitError, isTokenLimitError, transcribeAudio };
|
|
344
|
+
export { OpenAIError, createCompletion, createCompletionWithRetry, getModelForCommand, getOpenAIMaxOutputTokensForCommand, getOpenAIReasoningForCommand, isRateLimitError, isTokenLimitError, transcribeAudio };
|
|
284
345
|
//# sourceMappingURL=openai.js.map
|
package/dist/util/openai.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai.js","sources":["../../src/util/openai.ts"],"sourcesContent":["import { OpenAI } from 'openai';\nimport { ChatCompletionMessageParam } from 'openai/resources';\nimport * as Storage from './storage';\nimport { getLogger } from '../logging';\nimport { archiveAudio } from './general';\nimport { Config } from '../types';\nimport { safeJsonParse } from './validation';\n// eslint-disable-next-line no-restricted-imports\nimport fs from 'fs';\n\nexport interface Transcription {\n text: string;\n}\n\n/**\n * Get the appropriate model to use based on command-specific configuration\n * Command-specific model overrides the global model setting\n */\nexport function getModelForCommand(config: Config, commandName: string): string {\n let commandModel: string | undefined;\n\n switch (commandName) {\n case 'commit':\n case 'audio-commit':\n commandModel = config.commit?.model;\n break;\n case 'release':\n commandModel = config.release?.model;\n break;\n case 'review':\n case 'audio-review':\n commandModel = config.review?.model;\n break;\n default:\n // For other commands, just use global model\n break;\n }\n\n // Return command-specific model if available, otherwise global model\n return commandModel || config.model || 'gpt-4o-mini';\n}\n\nexport class OpenAIError extends Error {\n constructor(message: string, public readonly isTokenLimitError: boolean = false) {\n super(message);\n this.name = 'OpenAIError';\n }\n}\n\n// Check if an error is a token limit exceeded error\nexport function isTokenLimitError(error: any): boolean {\n if (!error?.message) return false;\n\n const message = error.message.toLowerCase();\n return message.includes('maximum context length') ||\n message.includes('context_length_exceeded') ||\n message.includes('token limit') ||\n message.includes('too many tokens') ||\n message.includes('reduce the length');\n}\n\n// Check if an error is a rate limit error\nexport function isRateLimitError(error: any): boolean {\n if (!error?.message && !error?.code && !error?.status) return false;\n\n // Check for OpenAI specific rate limit indicators\n if (error.status === 429 || error.code === 'rate_limit_exceeded') {\n return true;\n }\n\n const message = error.message.toLowerCase();\n return message.includes('rate limit exceeded') ||\n message.includes('too many requests') ||\n message.includes('quota exceeded') ||\n (message.includes('rate') && message.includes('limit'));\n}\n\nexport async function createCompletion(messages: ChatCompletionMessageParam[], options: { responseFormat?: any, model?: string, debug?: boolean, debugFile?: string, debugRequestFile?: string, debugResponseFile?: string, maxTokens?: number } = { model: \"gpt-4o-mini\" }): Promise<string | any> {\n const logger = getLogger();\n const storage = Storage.create({ log: logger.debug });\n let openai: OpenAI | null = null;\n try {\n const apiKey = process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new OpenAIError('OPENAI_API_KEY environment variable is not set');\n }\n\n // Create the client which we'll close in the finally block.\n const timeoutMs = parseInt(process.env.OPENAI_TIMEOUT_MS || '300000'); // Default to 5 minutes\n openai = new OpenAI({\n apiKey: apiKey,\n timeout: timeoutMs,\n });\n\n const modelToUse = options.model || \"gpt-4o-mini\";\n logger.info('🤖 Making request to OpenAI using model: %s', modelToUse);\n logger.debug('Sending prompt to OpenAI: %j', messages);\n\n // Use provided maxTokens or default to 10000\n const maxCompletionTokens = options.maxTokens || 10000;\n\n // Save request debug file if enabled\n if (options.debug && (options.debugRequestFile || options.debugFile)) {\n const requestData = {\n model: modelToUse,\n messages,\n max_completion_tokens: maxCompletionTokens,\n response_format: options.responseFormat,\n };\n const debugFile = options.debugRequestFile || options.debugFile;\n await storage.writeFile(debugFile!, JSON.stringify(requestData, null, 2), 'utf8');\n logger.debug('Wrote request debug file to %s', debugFile);\n }\n\n // Add timeout wrapper to the OpenAI API call\n const completionPromise = openai.chat.completions.create({\n model: modelToUse,\n messages,\n max_completion_tokens: maxCompletionTokens,\n response_format: options.responseFormat,\n });\n\n // Create timeout promise with proper cleanup to prevent memory leaks\n let timeoutId: NodeJS.Timeout | null = null;\n const timeoutPromise = new Promise<never>((_, reject) => {\n const timeoutMs = parseInt(process.env.OPENAI_TIMEOUT_MS || '300000'); // Default to 5 minutes\n timeoutId = setTimeout(() => reject(new OpenAIError(`OpenAI API call timed out after ${timeoutMs/1000} seconds`)), timeoutMs);\n });\n\n let completion;\n try {\n completion = await Promise.race([completionPromise, timeoutPromise]);\n } finally {\n // Clear the timeout to prevent memory leaks\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n }\n }\n\n // Save response debug file if enabled\n if (options.debug && (options.debugResponseFile || options.debugFile)) {\n const debugFile = options.debugResponseFile || options.debugFile;\n await storage.writeFile(debugFile!, JSON.stringify(completion, null, 2), 'utf8');\n logger.debug('Wrote response debug file to %s', debugFile);\n }\n\n const response = completion.choices[0]?.message?.content?.trim();\n if (!response) {\n throw new OpenAIError('No response received from OpenAI');\n }\n\n logger.debug('Received response from OpenAI: %s...', response.substring(0, 30));\n if (options.responseFormat) {\n return safeJsonParse(response, 'OpenAI API response');\n } else {\n return response;\n }\n\n } catch (error: any) {\n logger.error('Error calling OpenAI API: %s %s', error.message, error.stack);\n const isTokenError = isTokenLimitError(error);\n throw new OpenAIError(`Failed to create completion: ${error.message}`, isTokenError);\n } finally {\n // OpenAI client cleanup is handled automatically by the library\n // No manual cleanup needed for newer versions\n }\n}\n\n// Create completion with automatic retry on token limit errors\nexport async function createCompletionWithRetry(\n messages: ChatCompletionMessageParam[],\n options: { responseFormat?: any, model?: string, debug?: boolean, debugFile?: string, debugRequestFile?: string, debugResponseFile?: string, maxTokens?: number } = { model: \"gpt-4o-mini\" },\n retryCallback?: (attempt: number) => Promise<ChatCompletionMessageParam[]>\n): Promise<string | any> {\n const logger = getLogger();\n const maxRetries = 3;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const messagesToSend = attempt === 1 ? messages : (retryCallback ? await retryCallback(attempt) : messages);\n return await createCompletion(messagesToSend, options);\n } catch (error: any) {\n if (error instanceof OpenAIError && error.isTokenLimitError && attempt < maxRetries && retryCallback) {\n logger.warn('Token limit exceeded on attempt %d/%d, retrying with reduced content...', attempt, maxRetries);\n // Add exponential backoff for token limit errors\n const backoffMs = Math.min(1000 * Math.pow(2, attempt - 1), 10000);\n await new Promise(resolve => setTimeout(resolve, backoffMs));\n continue;\n } else if (isRateLimitError(error) && attempt < maxRetries) {\n // Handle rate limiting with exponential backoff\n const backoffMs = Math.min(2000 * Math.pow(2, attempt - 1), 15000); // More reasonable backoff: 2s, 4s, 8s, max 15s\n logger.warn(`Rate limit hit on attempt ${attempt}/${maxRetries}, waiting ${backoffMs}ms before retry...`);\n await new Promise(resolve => setTimeout(resolve, backoffMs));\n continue;\n }\n throw error;\n }\n }\n\n // This should never be reached, but TypeScript requires it\n throw new OpenAIError('Max retries exceeded');\n}\n\nexport async function transcribeAudio(filePath: string, options: { model?: string, debug?: boolean, debugFile?: string, debugRequestFile?: string, debugResponseFile?: string, outputDirectory?: string } = { model: \"whisper-1\" }): Promise<Transcription> {\n const logger = getLogger();\n const storage = Storage.create({ log: logger.debug });\n let openai: OpenAI | null = null;\n let audioStream: fs.ReadStream | null = null;\n let streamClosed = false;\n\n // Helper function to safely close the stream\n const closeAudioStream = () => {\n if (audioStream && !streamClosed) {\n try {\n // Only call destroy if it exists and the stream isn't already destroyed\n if (typeof audioStream.destroy === 'function' && !audioStream.destroyed) {\n audioStream.destroy();\n }\n streamClosed = true;\n logger.debug('Audio stream closed successfully');\n } catch (streamErr) {\n logger.debug('Failed to destroy audio read stream: %s', (streamErr as Error).message);\n streamClosed = true; // Mark as closed even if destroy failed\n }\n }\n };\n\n try {\n const apiKey = process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new OpenAIError('OPENAI_API_KEY environment variable is not set');\n }\n\n openai = new OpenAI({\n apiKey: apiKey,\n });\n\n logger.debug('Transcribing audio file: %s', filePath);\n\n // Save request debug file if enabled\n if (options.debug && (options.debugRequestFile || options.debugFile)) {\n const requestData = {\n model: options.model || \"whisper-1\",\n file: filePath, // Can't serialize the stream, so just save the file path\n response_format: \"json\",\n };\n const debugFile = options.debugRequestFile || options.debugFile;\n await storage.writeFile(debugFile!, JSON.stringify(requestData, null, 2), 'utf8');\n logger.debug('Wrote request debug file to %s', debugFile);\n }\n\n audioStream = await storage.readStream(filePath);\n\n // Set up error handler for the stream to ensure cleanup on stream errors\n // Only add handler if the stream has the 'on' method (real streams)\n if (audioStream && typeof audioStream.on === 'function') {\n audioStream.on('error', (streamError) => {\n logger.error('Audio stream error: %s', streamError.message);\n closeAudioStream();\n });\n }\n\n let transcription;\n try {\n transcription = await openai.audio.transcriptions.create({\n model: options.model || \"whisper-1\",\n file: audioStream,\n response_format: \"json\",\n });\n // Close the stream immediately after successful API call to prevent race conditions\n closeAudioStream();\n } catch (apiError) {\n // Close the stream immediately if the API call fails\n closeAudioStream();\n throw apiError;\n }\n\n // Save response debug file if enabled\n if (options.debug && (options.debugResponseFile || options.debugFile)) {\n const debugFile = options.debugResponseFile || options.debugFile;\n await storage.writeFile(debugFile!, JSON.stringify(transcription, null, 2), 'utf8');\n logger.debug('Wrote response debug file to %s', debugFile);\n }\n\n const response = transcription;\n if (!response) {\n throw new OpenAIError('No transcription received from OpenAI');\n }\n\n logger.debug('Received transcription from OpenAI: %s', response);\n\n // Archive the audio file and transcription\n try {\n const outputDir = options.outputDirectory || 'output';\n await archiveAudio(filePath, response.text, outputDir);\n } catch (archiveError: any) {\n // Don't fail the transcription if archiving fails, just log the error\n logger.warn('Failed to archive audio file: %s', archiveError.message);\n }\n\n return response;\n\n } catch (error: any) {\n logger.error('Error transcribing audio file: %s %s', error.message, error.stack);\n throw new OpenAIError(`Failed to transcribe audio: ${error.message}`);\n } finally {\n // Ensure the audio stream is properly closed to release file handles\n closeAudioStream();\n // OpenAI client cleanup is handled automatically by the library\n // No manual cleanup needed for newer versions\n }\n}\n"],"names":["getModelForCommand","config","commandName","commandModel","commit","model","release","review","OpenAIError","Error","message","isTokenLimitError","name","error","toLowerCase","includes","isRateLimitError","code","status","createCompletion","messages","options","logger","getLogger","storage","Storage","log","debug","openai","completion","apiKey","process","env","OPENAI_API_KEY","timeoutMs","parseInt","OPENAI_TIMEOUT_MS","OpenAI","timeout","modelToUse","info","maxCompletionTokens","maxTokens","debugRequestFile","debugFile","requestData","max_completion_tokens","response_format","responseFormat","writeFile","JSON","stringify","completionPromise","chat","completions","create","timeoutId","timeoutPromise","Promise","_","reject","setTimeout","race","clearTimeout","debugResponseFile","response","choices","content","trim","substring","safeJsonParse","stack","isTokenError","createCompletionWithRetry","retryCallback","maxRetries","attempt","messagesToSend","warn","backoffMs","Math","min","pow","resolve","transcribeAudio","filePath","audioStream","streamClosed","closeAudioStream","destroy","destroyed","streamErr","file","readStream","on","streamError","transcription","audio","transcriptions","apiError","outputDir","outputDirectory","archiveAudio","text","archiveError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"openai.js","sources":["../../src/util/openai.ts"],"sourcesContent":["import { OpenAI } from 'openai';\nimport { ChatCompletionMessageParam } from 'openai/resources';\nimport * as Storage from './storage';\nimport { getLogger } from '../logging';\nimport { archiveAudio } from './general';\nimport { Config } from '../types';\nimport { safeJsonParse } from './validation';\n// eslint-disable-next-line no-restricted-imports\nimport fs from 'fs';\n\nexport interface Transcription {\n text: string;\n}\n\n/**\n * Get the appropriate model to use based on command-specific configuration\n * Command-specific model overrides the global model setting\n */\nexport function getModelForCommand(config: Config, commandName: string): string {\n let commandModel: string | undefined;\n\n switch (commandName) {\n case 'commit':\n case 'audio-commit':\n commandModel = config.commit?.model;\n break;\n case 'release':\n commandModel = config.release?.model;\n break;\n case 'review':\n case 'audio-review':\n commandModel = config.review?.model;\n break;\n default:\n // For other commands, just use global model\n break;\n }\n\n // Return command-specific model if available, otherwise global model\n return commandModel || config.model || 'gpt-4o-mini';\n}\n\n/**\n * Get the appropriate OpenAI reasoning level based on command-specific configuration\n * Command-specific reasoning overrides the global reasoning setting\n */\nexport function getOpenAIReasoningForCommand(config: Config, commandName: string): 'low' | 'medium' | 'high' {\n let commandReasoning: 'low' | 'medium' | 'high' | undefined;\n\n switch (commandName) {\n case 'commit':\n case 'audio-commit':\n commandReasoning = config.commit?.openaiReasoning;\n break;\n case 'release':\n commandReasoning = config.release?.openaiReasoning;\n break;\n case 'review':\n case 'audio-review':\n commandReasoning = config.review?.openaiReasoning;\n break;\n default:\n // For other commands, just use global reasoning\n break;\n }\n\n // Return command-specific reasoning if available, otherwise global reasoning\n return commandReasoning || config.openaiReasoning || 'low';\n}\n\n/**\n * Get the appropriate OpenAI max output tokens based on command-specific configuration\n * Command-specific max output tokens overrides the global setting\n */\nexport function getOpenAIMaxOutputTokensForCommand(config: Config, commandName: string): number {\n let commandMaxOutputTokens: number | undefined;\n\n switch (commandName) {\n case 'commit':\n case 'audio-commit':\n commandMaxOutputTokens = config.commit?.openaiMaxOutputTokens;\n break;\n case 'release':\n commandMaxOutputTokens = config.release?.openaiMaxOutputTokens;\n break;\n case 'review':\n case 'audio-review':\n commandMaxOutputTokens = config.review?.openaiMaxOutputTokens;\n break;\n default:\n // For other commands, just use global max output tokens\n break;\n }\n\n // Return command-specific max output tokens if available, otherwise global setting\n return commandMaxOutputTokens || config.openaiMaxOutputTokens || 10000;\n}\n\nexport class OpenAIError extends Error {\n constructor(message: string, public readonly isTokenLimitError: boolean = false) {\n super(message);\n this.name = 'OpenAIError';\n }\n}\n\n// Check if an error is a token limit exceeded error\nexport function isTokenLimitError(error: any): boolean {\n if (!error?.message) return false;\n\n const message = error.message.toLowerCase();\n return message.includes('maximum context length') ||\n message.includes('context_length_exceeded') ||\n message.includes('token limit') ||\n message.includes('too many tokens') ||\n message.includes('reduce the length');\n}\n\n// Check if an error is a rate limit error\nexport function isRateLimitError(error: any): boolean {\n if (!error?.message && !error?.code && !error?.status) return false;\n\n // Check for OpenAI specific rate limit indicators\n if (error.status === 429 || error.code === 'rate_limit_exceeded') {\n return true;\n }\n\n // Only check message if it exists\n if (error.message) {\n const message = error.message.toLowerCase();\n return message.includes('rate limit exceeded') ||\n message.includes('too many requests') ||\n message.includes('quota exceeded') ||\n (message.includes('rate') && message.includes('limit'));\n }\n\n return false;\n}\n\nexport async function createCompletion(messages: ChatCompletionMessageParam[], options: { responseFormat?: any, model?: string, debug?: boolean, debugFile?: string, debugRequestFile?: string, debugResponseFile?: string, maxTokens?: number, openaiReasoning?: 'low' | 'medium' | 'high', openaiMaxOutputTokens?: number } = { model: \"gpt-4o-mini\" }): Promise<string | any> {\n const logger = getLogger();\n const storage = Storage.create({ log: logger.debug });\n let openai: OpenAI | null = null;\n try {\n const apiKey = process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new OpenAIError('OPENAI_API_KEY environment variable is not set');\n }\n\n // Create the client which we'll close in the finally block.\n const timeoutMs = parseInt(process.env.OPENAI_TIMEOUT_MS || '300000'); // Default to 5 minutes\n openai = new OpenAI({\n apiKey: apiKey,\n timeout: timeoutMs,\n });\n\n const modelToUse = options.model || \"gpt-4o-mini\";\n logger.info('🤖 Making request to OpenAI using model: %s', modelToUse);\n logger.debug('Sending prompt to OpenAI: %j', messages);\n\n // Use openaiMaxOutputTokens if specified (highest priority), otherwise fall back to maxTokens, or default to 10000\n const maxCompletionTokens = options.openaiMaxOutputTokens ?? options.maxTokens ?? 10000;\n\n // Save request debug file if enabled\n if (options.debug && (options.debugRequestFile || options.debugFile)) {\n const requestData = {\n model: modelToUse,\n messages,\n max_completion_tokens: maxCompletionTokens,\n response_format: options.responseFormat,\n reasoning_effort: options.openaiReasoning,\n };\n const debugFile = options.debugRequestFile || options.debugFile;\n await storage.writeFile(debugFile!, JSON.stringify(requestData, null, 2), 'utf8');\n logger.debug('Wrote request debug file to %s', debugFile);\n }\n\n // Prepare the API call options\n const apiOptions: any = {\n model: modelToUse,\n messages,\n max_completion_tokens: maxCompletionTokens,\n response_format: options.responseFormat,\n };\n\n // Add reasoning parameter if specified and model supports it\n if (options.openaiReasoning && (modelToUse.includes('gpt-5') || modelToUse.includes('o3'))) {\n apiOptions.reasoning_effort = options.openaiReasoning;\n logger.debug('Using OpenAI reasoning level: %s', options.openaiReasoning);\n }\n\n // Add timeout wrapper to the OpenAI API call\n const completionPromise = openai.chat.completions.create(apiOptions);\n\n // Create timeout promise with proper cleanup to prevent memory leaks\n let timeoutId: NodeJS.Timeout | null = null;\n const timeoutPromise = new Promise<never>((_, reject) => {\n const timeoutMs = parseInt(process.env.OPENAI_TIMEOUT_MS || '300000'); // Default to 5 minutes\n timeoutId = setTimeout(() => reject(new OpenAIError(`OpenAI API call timed out after ${timeoutMs/1000} seconds`)), timeoutMs);\n });\n\n let completion;\n try {\n completion = await Promise.race([completionPromise, timeoutPromise]);\n } finally {\n // Clear the timeout to prevent memory leaks\n if (timeoutId !== null) {\n clearTimeout(timeoutId);\n }\n }\n\n // Save response debug file if enabled\n if (options.debug && (options.debugResponseFile || options.debugFile)) {\n const debugFile = options.debugResponseFile || options.debugFile;\n await storage.writeFile(debugFile!, JSON.stringify(completion, null, 2), 'utf8');\n logger.debug('Wrote response debug file to %s', debugFile);\n }\n\n const response = completion.choices[0]?.message?.content?.trim();\n if (!response) {\n throw new OpenAIError('No response received from OpenAI');\n }\n\n logger.debug('Received response from OpenAI: %s...', response.substring(0, 30));\n if (options.responseFormat) {\n return safeJsonParse(response, 'OpenAI API response');\n } else {\n return response;\n }\n\n } catch (error: any) {\n logger.error('Error calling OpenAI API: %s %s', error.message, error.stack);\n const isTokenError = isTokenLimitError(error);\n throw new OpenAIError(`Failed to create completion: ${error.message}`, isTokenError);\n } finally {\n // OpenAI client cleanup is handled automatically by the library\n // No manual cleanup needed for newer versions\n }\n}\n\n// Create completion with automatic retry on token limit errors\nexport async function createCompletionWithRetry(\n messages: ChatCompletionMessageParam[],\n options: { responseFormat?: any, model?: string, debug?: boolean, debugFile?: string, debugRequestFile?: string, debugResponseFile?: string, maxTokens?: number, openaiReasoning?: 'low' | 'medium' | 'high', openaiMaxOutputTokens?: number } = { model: \"gpt-4o-mini\" },\n retryCallback?: (attempt: number) => Promise<ChatCompletionMessageParam[]>\n): Promise<string | any> {\n const logger = getLogger();\n const maxRetries = 3;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const messagesToSend = attempt === 1 ? messages : (retryCallback ? await retryCallback(attempt) : messages);\n return await createCompletion(messagesToSend, options);\n } catch (error: any) {\n if (error instanceof OpenAIError && error.isTokenLimitError && attempt < maxRetries && retryCallback) {\n logger.warn('Token limit exceeded on attempt %d/%d, retrying with reduced content...', attempt, maxRetries);\n // Add exponential backoff for token limit errors\n const backoffMs = Math.min(1000 * Math.pow(2, attempt - 1), 10000);\n await new Promise(resolve => setTimeout(resolve, backoffMs));\n continue;\n } else if (isRateLimitError(error) && attempt < maxRetries) {\n // Handle rate limiting with exponential backoff\n const backoffMs = Math.min(2000 * Math.pow(2, attempt - 1), 15000); // More reasonable backoff: 2s, 4s, 8s, max 15s\n logger.warn(`Rate limit hit on attempt ${attempt}/${maxRetries}, waiting ${backoffMs}ms before retry...`);\n await new Promise(resolve => setTimeout(resolve, backoffMs));\n continue;\n }\n throw error;\n }\n }\n\n // This should never be reached, but TypeScript requires it\n throw new OpenAIError('Max retries exceeded');\n}\n\nexport async function transcribeAudio(filePath: string, options: { model?: string, debug?: boolean, debugFile?: string, debugRequestFile?: string, debugResponseFile?: string, outputDirectory?: string } = { model: \"whisper-1\" }): Promise<Transcription> {\n const logger = getLogger();\n const storage = Storage.create({ log: logger.debug });\n let openai: OpenAI | null = null;\n let audioStream: fs.ReadStream | null = null;\n let streamClosed = false;\n\n // Helper function to safely close the stream\n const closeAudioStream = () => {\n if (audioStream && !streamClosed) {\n try {\n // Only call destroy if it exists and the stream isn't already destroyed\n if (typeof audioStream.destroy === 'function' && !audioStream.destroyed) {\n audioStream.destroy();\n }\n streamClosed = true;\n logger.debug('Audio stream closed successfully');\n } catch (streamErr) {\n logger.debug('Failed to destroy audio read stream: %s', (streamErr as Error).message);\n streamClosed = true; // Mark as closed even if destroy failed\n }\n }\n };\n\n try {\n const apiKey = process.env.OPENAI_API_KEY;\n if (!apiKey) {\n throw new OpenAIError('OPENAI_API_KEY environment variable is not set');\n }\n\n openai = new OpenAI({\n apiKey: apiKey,\n });\n\n logger.debug('Transcribing audio file: %s', filePath);\n\n // Save request debug file if enabled\n if (options.debug && (options.debugRequestFile || options.debugFile)) {\n const requestData = {\n model: options.model || \"whisper-1\",\n file: filePath, // Can't serialize the stream, so just save the file path\n response_format: \"json\",\n };\n const debugFile = options.debugRequestFile || options.debugFile;\n await storage.writeFile(debugFile!, JSON.stringify(requestData, null, 2), 'utf8');\n logger.debug('Wrote request debug file to %s', debugFile);\n }\n\n audioStream = await storage.readStream(filePath);\n\n // Set up error handler for the stream to ensure cleanup on stream errors\n // Only add handler if the stream has the 'on' method (real streams)\n if (audioStream && typeof audioStream.on === 'function') {\n audioStream.on('error', (streamError) => {\n logger.error('Audio stream error: %s', streamError.message);\n closeAudioStream();\n });\n }\n\n let transcription;\n try {\n transcription = await openai.audio.transcriptions.create({\n model: options.model || \"whisper-1\",\n file: audioStream,\n response_format: \"json\",\n });\n // Close the stream immediately after successful API call to prevent race conditions\n closeAudioStream();\n } catch (apiError) {\n // Close the stream immediately if the API call fails\n closeAudioStream();\n throw apiError;\n }\n\n // Save response debug file if enabled\n if (options.debug && (options.debugResponseFile || options.debugFile)) {\n const debugFile = options.debugResponseFile || options.debugFile;\n await storage.writeFile(debugFile!, JSON.stringify(transcription, null, 2), 'utf8');\n logger.debug('Wrote response debug file to %s', debugFile);\n }\n\n const response = transcription;\n if (!response) {\n throw new OpenAIError('No transcription received from OpenAI');\n }\n\n logger.debug('Received transcription from OpenAI: %s', response);\n\n // Archive the audio file and transcription\n try {\n const outputDir = options.outputDirectory || 'output';\n await archiveAudio(filePath, response.text, outputDir);\n } catch (archiveError: any) {\n // Don't fail the transcription if archiving fails, just log the error\n logger.warn('Failed to archive audio file: %s', archiveError.message);\n }\n\n return response;\n\n } catch (error: any) {\n logger.error('Error transcribing audio file: %s %s', error.message, error.stack);\n throw new OpenAIError(`Failed to transcribe audio: ${error.message}`);\n } finally {\n // Ensure the audio stream is properly closed to release file handles\n closeAudioStream();\n // OpenAI client cleanup is handled automatically by the library\n // No manual cleanup needed for newer versions\n }\n}\n"],"names":["getModelForCommand","config","commandName","commandModel","commit","model","release","review","getOpenAIReasoningForCommand","commandReasoning","openaiReasoning","getOpenAIMaxOutputTokensForCommand","commandMaxOutputTokens","openaiMaxOutputTokens","OpenAIError","Error","message","isTokenLimitError","name","error","toLowerCase","includes","isRateLimitError","code","status","createCompletion","messages","options","logger","getLogger","storage","Storage","log","debug","openai","completion","apiKey","process","env","OPENAI_API_KEY","timeoutMs","parseInt","OPENAI_TIMEOUT_MS","OpenAI","timeout","modelToUse","info","maxCompletionTokens","maxTokens","debugRequestFile","debugFile","requestData","max_completion_tokens","response_format","responseFormat","reasoning_effort","writeFile","JSON","stringify","apiOptions","completionPromise","chat","completions","create","timeoutId","timeoutPromise","Promise","_","reject","setTimeout","race","clearTimeout","debugResponseFile","response","choices","content","trim","substring","safeJsonParse","stack","isTokenError","createCompletionWithRetry","retryCallback","maxRetries","attempt","messagesToSend","warn","backoffMs","Math","min","pow","resolve","transcribeAudio","filePath","audioStream","streamClosed","closeAudioStream","destroy","destroyed","streamErr","file","readStream","on","streamError","transcription","audio","transcriptions","apiError","outputDir","outputDirectory","archiveAudio","text","archiveError"],"mappings":"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"}
|
package/dist/util/validation.js
CHANGED
|
@@ -39,6 +39,29 @@
|
|
|
39
39
|
}
|
|
40
40
|
return value;
|
|
41
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Sanitizes and truncates direction parameter for safe use in prompts
|
|
44
|
+
* @param direction The direction string to sanitize
|
|
45
|
+
* @param maxLength Maximum length before truncation (default: 2000)
|
|
46
|
+
* @returns Sanitized and truncated direction string
|
|
47
|
+
*/ const sanitizeDirection = (direction, maxLength = 2000)=>{
|
|
48
|
+
if (!direction) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
// Remove newlines and excessive whitespace to prevent template breakage
|
|
52
|
+
const sanitized = direction.replace(/\r?\n/g, ' ') // Replace newlines with spaces
|
|
53
|
+
.replace(/\s+/g, ' ') // Replace multiple whitespace with single space
|
|
54
|
+
.trim();
|
|
55
|
+
// Truncate if too long
|
|
56
|
+
if (sanitized.length > maxLength) {
|
|
57
|
+
const truncated = sanitized.substring(0, maxLength - 3) + '...';
|
|
58
|
+
// Log truncation for debugging
|
|
59
|
+
// eslint-disable-next-line no-console
|
|
60
|
+
console.warn(`Direction truncated from ${sanitized.length} to ${truncated.length} characters`);
|
|
61
|
+
return truncated;
|
|
62
|
+
}
|
|
63
|
+
return sanitized;
|
|
64
|
+
};
|
|
42
65
|
/**
|
|
43
66
|
* Validates package.json structure has basic required fields
|
|
44
67
|
*/ const validatePackageJson = (data, context, requireName = true)=>{
|
|
@@ -53,5 +76,5 @@
|
|
|
53
76
|
return data;
|
|
54
77
|
};
|
|
55
78
|
|
|
56
|
-
export { safeJsonParse, validatePackageJson, validateReleaseSummary, validateString };
|
|
79
|
+
export { safeJsonParse, sanitizeDirection, validatePackageJson, validateReleaseSummary, validateString };
|
|
57
80
|
//# sourceMappingURL=validation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.js","sources":["../../src/util/validation.ts"],"sourcesContent":["/**\n * Runtime validation utilities for safe type handling\n */\n\nexport interface ReleaseSummary {\n title: string;\n body: string;\n}\n\n\n\nexport interface TranscriptionResult {\n text: string;\n [key: string]: any;\n}\n\n/**\n * Validates and safely casts data to ReleaseSummary type\n */\nexport const validateReleaseSummary = (data: any): ReleaseSummary => {\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid release summary: not an object');\n }\n if (typeof data.title !== 'string') {\n throw new Error('Invalid release summary: title must be a string');\n }\n if (typeof data.body !== 'string') {\n throw new Error('Invalid release summary: body must be a string');\n }\n return data as ReleaseSummary;\n};\n\n\n\n/**\n * Validates transcription result has required text property\n */\nexport const validateTranscriptionResult = (data: any): TranscriptionResult => {\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid transcription result: not an object');\n }\n if (typeof data.text !== 'string') {\n throw new Error('Invalid transcription result: text property must be a string');\n }\n return data as TranscriptionResult;\n};\n\n/**\n * Safely parses JSON with error handling\n */\nexport const safeJsonParse = <T = any>(jsonString: string, context?: string): T => {\n try {\n const parsed = JSON.parse(jsonString);\n if (parsed === null || parsed === undefined) {\n throw new Error('Parsed JSON is null or undefined');\n }\n return parsed;\n } catch (error) {\n const contextStr = context ? ` (${context})` : '';\n throw new Error(`Failed to parse JSON${contextStr}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n};\n\n/**\n * Validates that a value is a non-empty string\n */\nexport const validateString = (value: any, fieldName: string): string => {\n if (typeof value !== 'string') {\n throw new Error(`${fieldName} must be a string, got ${typeof value}`);\n }\n if (value.trim() === '') {\n throw new Error(`${fieldName} cannot be empty`);\n }\n return value;\n};\n\n/**\n * Validates that a value exists and has a specific property\n */\nexport const validateHasProperty = (obj: any, property: string, context?: string): void => {\n if (!obj || typeof obj !== 'object') {\n const contextStr = context ? ` in ${context}` : '';\n throw new Error(`Object is null or not an object${contextStr}`);\n }\n if (!(property in obj)) {\n const contextStr = context ? ` in ${context}` : '';\n throw new Error(`Missing required property '${property}'${contextStr}`);\n }\n};\n\n/**\n * Validates package.json structure has basic required fields\n */\nexport const validatePackageJson = (data: any, context?: string, requireName: boolean = true): any => {\n if (!data || typeof data !== 'object') {\n const contextStr = context ? ` (${context})` : '';\n throw new Error(`Invalid package.json${contextStr}: not an object`);\n }\n if (requireName && typeof data.name !== 'string') {\n const contextStr = context ? ` (${context})` : '';\n throw new Error(`Invalid package.json${contextStr}: name must be a string`);\n }\n return data;\n};\n"],"names":["validateReleaseSummary","data","Error","title","body","safeJsonParse","jsonString","context","parsed","JSON","parse","undefined","error","contextStr","message","validateString","value","fieldName","trim","validatePackageJson","requireName","name"],"mappings":"AAAA;;;;IAmBO,MAAMA,sBAAAA,GAAyB,CAACC,IAAAA,GAAAA;AACnC,IAAA,IAAI,CAACA,IAAAA,IAAQ,OAAOA,IAAAA,KAAS,QAAA,EAAU;AACnC,QAAA,MAAM,IAAIC,KAAAA,CAAM,wCAAA,CAAA;AACpB,IAAA;AACA,IAAA,IAAI,OAAOD,IAAAA,CAAKE,KAAK,KAAK,QAAA,EAAU;AAChC,QAAA,MAAM,IAAID,KAAAA,CAAM,iDAAA,CAAA;AACpB,IAAA;AACA,IAAA,IAAI,OAAOD,IAAAA,CAAKG,IAAI,KAAK,QAAA,EAAU;AAC/B,QAAA,MAAM,IAAIF,KAAAA,CAAM,gDAAA,CAAA;AACpB,IAAA;IACA,OAAOD,IAAAA;AACX;AAiBA;;AAEC,IACM,MAAMI,aAAAA,GAAgB,CAAUC,UAAAA,EAAoBC,OAAAA,GAAAA;IACvD,IAAI;QACA,MAAMC,MAAAA,GAASC,IAAAA,CAAKC,KAAK,CAACJ,UAAAA,CAAAA;QAC1B,IAAIE,MAAAA,KAAW,IAAA,IAAQA,MAAAA,KAAWG,SAAAA,EAAW;AACzC,YAAA,MAAM,IAAIT,KAAAA,CAAM,kCAAA,CAAA;AACpB,QAAA;QACA,OAAOM,MAAAA;AACX,IAAA,CAAA,CAAE,OAAOI,KAAAA,EAAO;QACZ,MAAMC,UAAAA,GAAaN,UAAU,CAAC,EAAE,EAAEA,OAAAA,CAAQ,CAAC,CAAC,GAAG,EAAA;AAC/C,QAAA,MAAM,IAAIL,KAAAA,CAAM,CAAC,oBAAoB,EAAEW,UAAAA,CAAW,EAAE,EAAED,KAAAA,YAAiBV,KAAAA,GAAQU,KAAAA,CAAME,OAAO,GAAG,eAAA,CAAA,CAAiB,CAAA;AACpH,IAAA;AACJ;AAEA;;AAEC,IACM,MAAMC,cAAAA,GAAiB,CAACC,KAAAA,EAAYC,SAAAA,GAAAA;IACvC,IAAI,OAAOD,UAAU,QAAA,EAAU;AAC3B,QAAA,MAAM,IAAId,KAAAA,CAAM,CAAA,EAAGe,UAAU,uBAAuB,EAAE,OAAOD,KAAAA,CAAAA,CAAO,CAAA;AACxE,IAAA;IACA,IAAIA,KAAAA,CAAME,IAAI,EAAA,KAAO,EAAA,EAAI;AACrB,QAAA,MAAM,IAAIhB,KAAAA,CAAM,CAAA,EAAGe,SAAAA,CAAU,gBAAgB,CAAC,CAAA;AAClD,IAAA;IACA,OAAOD,KAAAA;AACX;AAgBA;;AAEC,IACM,
|
|
1
|
+
{"version":3,"file":"validation.js","sources":["../../src/util/validation.ts"],"sourcesContent":["/**\n * Runtime validation utilities for safe type handling\n */\n\nexport interface ReleaseSummary {\n title: string;\n body: string;\n}\n\n\n\nexport interface TranscriptionResult {\n text: string;\n [key: string]: any;\n}\n\n/**\n * Validates and safely casts data to ReleaseSummary type\n */\nexport const validateReleaseSummary = (data: any): ReleaseSummary => {\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid release summary: not an object');\n }\n if (typeof data.title !== 'string') {\n throw new Error('Invalid release summary: title must be a string');\n }\n if (typeof data.body !== 'string') {\n throw new Error('Invalid release summary: body must be a string');\n }\n return data as ReleaseSummary;\n};\n\n\n\n/**\n * Validates transcription result has required text property\n */\nexport const validateTranscriptionResult = (data: any): TranscriptionResult => {\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid transcription result: not an object');\n }\n if (typeof data.text !== 'string') {\n throw new Error('Invalid transcription result: text property must be a string');\n }\n return data as TranscriptionResult;\n};\n\n/**\n * Safely parses JSON with error handling\n */\nexport const safeJsonParse = <T = any>(jsonString: string, context?: string): T => {\n try {\n const parsed = JSON.parse(jsonString);\n if (parsed === null || parsed === undefined) {\n throw new Error('Parsed JSON is null or undefined');\n }\n return parsed;\n } catch (error) {\n const contextStr = context ? ` (${context})` : '';\n throw new Error(`Failed to parse JSON${contextStr}: ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n};\n\n/**\n * Validates that a value is a non-empty string\n */\nexport const validateString = (value: any, fieldName: string): string => {\n if (typeof value !== 'string') {\n throw new Error(`${fieldName} must be a string, got ${typeof value}`);\n }\n if (value.trim() === '') {\n throw new Error(`${fieldName} cannot be empty`);\n }\n return value;\n};\n\n/**\n * Sanitizes and truncates direction parameter for safe use in prompts\n * @param direction The direction string to sanitize\n * @param maxLength Maximum length before truncation (default: 2000)\n * @returns Sanitized and truncated direction string\n */\nexport const sanitizeDirection = (direction: string | undefined, maxLength: number = 2000): string | undefined => {\n if (!direction) {\n return undefined;\n }\n\n // Remove newlines and excessive whitespace to prevent template breakage\n const sanitized = direction\n .replace(/\\r?\\n/g, ' ') // Replace newlines with spaces\n .replace(/\\s+/g, ' ') // Replace multiple whitespace with single space\n .trim();\n\n // Truncate if too long\n if (sanitized.length > maxLength) {\n const truncated = sanitized.substring(0, maxLength - 3) + '...';\n // Log truncation for debugging\n // eslint-disable-next-line no-console\n console.warn(`Direction truncated from ${sanitized.length} to ${truncated.length} characters`);\n return truncated;\n }\n\n return sanitized;\n};\n\n/**\n * Validates that a value exists and has a specific property\n */\nexport const validateHasProperty = (obj: any, property: string, context?: string): void => {\n if (!obj || typeof obj !== 'object') {\n const contextStr = context ? ` in ${context}` : '';\n throw new Error(`Object is null or not an object${contextStr}`);\n }\n if (!(property in obj)) {\n const contextStr = context ? ` in ${context}` : '';\n throw new Error(`Missing required property '${property}'${contextStr}`);\n }\n};\n\n/**\n * Validates package.json structure has basic required fields\n */\nexport const validatePackageJson = (data: any, context?: string, requireName: boolean = true): any => {\n if (!data || typeof data !== 'object') {\n const contextStr = context ? ` (${context})` : '';\n throw new Error(`Invalid package.json${contextStr}: not an object`);\n }\n if (requireName && typeof data.name !== 'string') {\n const contextStr = context ? ` (${context})` : '';\n throw new Error(`Invalid package.json${contextStr}: name must be a string`);\n }\n return data;\n};\n"],"names":["validateReleaseSummary","data","Error","title","body","safeJsonParse","jsonString","context","parsed","JSON","parse","undefined","error","contextStr","message","validateString","value","fieldName","trim","sanitizeDirection","direction","maxLength","sanitized","replace","length","truncated","substring","console","warn","validatePackageJson","requireName","name"],"mappings":"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"}
|