@changesmith/cli 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +206 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1258 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/config.ts","../src/git.ts","../src/commands/generate.ts","../src/api.ts","../src/changelog.ts","../src/commands/local.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/commands/status.ts","../src/commands/config.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { initCommand } from './commands/init.js'\nimport { githubCommand } from './commands/generate.js'\nimport { localCommand } from './commands/local.js'\nimport { loginCommand } from './commands/login.js'\nimport { logoutCommand } from './commands/logout.js'\nimport { statusCommand } from './commands/status.js'\nimport { configCommand } from './commands/config.js'\n\ndeclare const __CLI_VERSION__: string\n\nconst program = new Command()\n\nprogram\n .name('changesmith')\n .description('Generate beautiful changelogs from your git history')\n .version(__CLI_VERSION__)\n\nprogram.addCommand(initCommand)\nprogram.addCommand(localCommand)\nprogram.addCommand(githubCommand)\nprogram.addCommand(loginCommand)\nprogram.addCommand(logoutCommand)\nprogram.addCommand(statusCommand)\nprogram.addCommand(configCommand)\n\n// Hidden alias: `changesmith generate` → `changesmith github` (backwards compat)\nconst generateAlias = new Command('generate')\n .description('Alias for \"github\" command')\n .allowUnknownOption(true)\n .allowExcessArguments(true)\n .helpOption(false)\n .action(async function () {\n // Forward to githubCommand using Commander's parsed args\n await githubCommand.parseAsync(['node', 'github', ...generateAlias.args])\n })\nprogram.addCommand(generateAlias, { hidden: true })\n\nprogram.parse()\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport {\n projectConfigExists,\n writeProjectConfig,\n getDefaultProjectConfig,\n getProjectConfigPath,\n} from '../config.js'\nimport { isGitRepo, getDefaultBranch, getRemoteUrl, parseRepoFromUrl } from '../git.js'\n\nexport const initCommand = new Command('init')\n .description('Initialize Changesmith in the current repository')\n .option('-f, --force', 'Overwrite existing config')\n .action(async (options) => {\n const spinner = ora('Detecting git repository...').start()\n\n // Check if we're in a git repo\n if (!(await isGitRepo())) {\n spinner.fail('Not a git repository')\n console.log(chalk.gray('Run this command from the root of a git repository.'))\n process.exit(1)\n }\n\n spinner.succeed('Git repository detected')\n\n // Check for existing config\n if (await projectConfigExists()) {\n if (!options.force) {\n console.log(chalk.yellow('Changesmith is already initialized in this repository.'))\n console.log(chalk.gray(`Config file: ${getProjectConfigPath()}`))\n console.log(chalk.gray('Use --force to overwrite the existing config.'))\n process.exit(0)\n }\n }\n\n // Detect repository info\n const defaultBranch = await getDefaultBranch()\n const remoteUrl = await getRemoteUrl()\n const repoInfo = remoteUrl ? parseRepoFromUrl(remoteUrl) : null\n\n // Create config\n const config = {\n ...getDefaultProjectConfig(),\n defaultBranch,\n }\n\n // Write config file\n const writeSpinner = ora('Creating config file...').start()\n await writeProjectConfig(config)\n writeSpinner.succeed('Created .changesmith.json')\n\n // Show summary\n console.log('')\n console.log(chalk.green('Changesmith initialized successfully!'))\n console.log('')\n\n if (repoInfo) {\n console.log(chalk.gray(`Repository: ${repoInfo.owner}/${repoInfo.repo}`))\n }\n console.log(chalk.gray(`Default branch: ${defaultBranch}`))\n console.log('')\n\n console.log('Next steps:')\n console.log(chalk.cyan(' 1. ') + 'Log in to Changesmith:')\n console.log(chalk.gray(' changesmith login'))\n console.log('')\n console.log(chalk.cyan(' 2. ') + 'Generate a changelog:')\n console.log(chalk.gray(' changesmith generate v1.0.0'))\n console.log('')\n console.log(chalk.gray(`Edit ${getProjectConfigPath()} to customize changelog generation.`))\n })\n","import Conf from 'conf'\nimport { readFile, writeFile, access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\n/**\n * Environment variable precedence:\n * CHANGESMITH_TOKEN and CHANGESMITH_API_URL take precedence over stored config.\n * Empty or whitespace-only env values are treated as unset, falling back to stored config.\n */\n\n/**\n * User config stored in ~/.changesmith (credentials, preferences)\n */\nexport interface UserConfig {\n token?: string\n userId?: string\n apiUrl?: string\n}\n\n/**\n * Project config stored in .changesmith.json (repo-specific settings)\n */\nexport interface ProjectConfig {\n version: 1\n defaultBranch?: string\n excludeTypes?: string[]\n includeScopes?: string[]\n excludeScopes?: string[]\n styleGuide?: string\n customPrompt?: string\n}\n\nconst CONFIG_FILE = '.changesmith.json'\n\n/**\n * User configuration store (persisted in ~/.changesmith)\n */\nconst userConfig = new Conf<UserConfig>({\n projectName: 'changesmith',\n schema: {\n token: { type: 'string' },\n userId: { type: 'string' },\n apiUrl: { type: 'string' },\n },\n})\n\n/**\n * Get the API URL (defaults to production)\n */\nexport function getApiUrl(): string {\n return getEnvApiUrl() ?? userConfig.get('apiUrl') ?? 'https://api.changesmith.dev'\n}\n\n/**\n * Set the API URL\n */\nexport function setApiUrl(url: string): void {\n userConfig.set('apiUrl', url)\n}\n\n// JWTs are typically 200+ chars — catches obvious typos/truncation\nexport const MIN_TOKEN_LENGTH = 50\n// Longer than any reasonable token — catches accidental file-path or base64-blob paste\nexport const MAX_TOKEN_LENGTH = 4096\n\n/**\n * Return the trimmed CHANGESMITH_TOKEN env value, or undefined if unset/blank.\n * Single source of truth for \"is a token present in the environment?\"\n */\nfunction getEnvToken(): string | undefined {\n const raw = process.env.CHANGESMITH_TOKEN?.trim()\n return raw || undefined\n}\n\n/**\n * Return the trimmed CHANGESMITH_API_URL env value, or undefined if unset/blank.\n * Warns once to stderr if the value is not a valid URL.\n */\nfunction getEnvApiUrl(): string | undefined {\n const raw = process.env.CHANGESMITH_API_URL?.trim()\n if (!raw) return undefined\n if (!envApiUrlWarned) {\n try {\n new URL(raw)\n } catch {\n envApiUrlWarned = true\n console.error(\n `Warning: CHANGESMITH_API_URL is not a valid URL (\"${raw}\") — API calls may fail.`\n )\n }\n }\n return raw\n}\n\n// Warning flags prevent repeated stderr noise within a single CLI invocation.\nlet envTokenWarned = false\nlet envApiUrlWarned = false\n\n/** @internal Reset warning state — for testing only */\nexport function _resetEnvWarnings(): void {\n envTokenWarned = false\n envApiUrlWarned = false\n}\n\n/**\n * Print a one-time warning to stderr if CHANGESMITH_TOKEN is set but\n * suspiciously short or long. Call this explicitly from command entry\n * points rather than from getAuthToken(), so callers like isLoggedIn()\n * don't accidentally trigger warnings.\n */\nexport function warnIfEnvTokenSuspicious(): void {\n const envToken = getEnvToken()\n if (!envToken || envTokenWarned) return\n if (envToken.length < MIN_TOKEN_LENGTH) {\n envTokenWarned = true\n console.error('Warning: CHANGESMITH_TOKEN looks too short — API calls may fail.')\n } else if (envToken.length > MAX_TOKEN_LENGTH) {\n envTokenWarned = true\n console.error('Warning: CHANGESMITH_TOKEN is unusually long — this may not be a valid token.')\n }\n}\n\n/**\n * Get the user's auth token.\n * Prefers CHANGESMITH_TOKEN env var over stored config.\n */\nexport function getAuthToken(): string | undefined {\n return getEnvToken() ?? userConfig.get('token')\n}\n\n/**\n * Set the user's auth token\n */\nexport function setAuthToken(token: string): void {\n userConfig.set('token', token)\n}\n\n/**\n * Get the user ID\n */\nexport function getUserId(): string | undefined {\n return userConfig.get('userId')\n}\n\n/**\n * Set the user ID\n */\nexport function setUserId(id: string): void {\n userConfig.set('userId', id)\n}\n\n/**\n * Clear all auth credentials\n */\nexport function clearAuth(): void {\n userConfig.delete('token')\n userConfig.delete('userId')\n}\n\n/**\n * Check if user is logged in (via stored token or environment variable)\n */\nexport function isLoggedIn(): boolean {\n return !!getAuthToken()\n}\n\n/**\n * Check if authentication is from environment variable\n */\nexport function isEnvAuth(): boolean {\n return !!getEnvToken()\n}\n\n/**\n * Check if API URL is from environment variable\n */\nexport function isEnvApiUrl(): boolean {\n return !!getEnvApiUrl()\n}\n\n/**\n * Check if stored credentials exist (independent of env auth)\n */\nexport function hasStoredToken(): boolean {\n return !!userConfig.get('token')\n}\n\n/**\n * Get the path to the project config file\n */\nexport function getProjectConfigPath(cwd: string = process.cwd()): string {\n return join(cwd, CONFIG_FILE)\n}\n\n/**\n * Check if project config exists\n */\nexport async function projectConfigExists(cwd: string = process.cwd()): Promise<boolean> {\n try {\n await access(getProjectConfigPath(cwd))\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Read project config from .changesmith.json\n */\nexport async function readProjectConfig(\n cwd: string = process.cwd()\n): Promise<ProjectConfig | null> {\n try {\n const content = await readFile(getProjectConfigPath(cwd), 'utf-8')\n return JSON.parse(content) as ProjectConfig\n } catch {\n return null\n }\n}\n\n/**\n * Write project config to .changesmith.json\n */\nexport async function writeProjectConfig(\n config: ProjectConfig,\n cwd: string = process.cwd()\n): Promise<void> {\n await writeFile(getProjectConfigPath(cwd), JSON.stringify(config, null, 2) + '\\n', 'utf-8')\n}\n\n/**\n * Get default project config\n */\nexport function getDefaultProjectConfig(): ProjectConfig {\n return {\n version: 1,\n excludeTypes: ['chore', 'style', 'ci'],\n }\n}\n","import { exec } from 'node:child_process'\nimport { promisify } from 'node:util'\nimport { access } from 'node:fs/promises'\nimport { join } from 'node:path'\n\nconst execAsync = promisify(exec)\n\n/**\n * Validate that a git ref does not contain shell metacharacters.\n * Allows: alphanumeric, dots, hyphens, underscores, slashes, @, ^, ~, {, }\n */\nconst SAFE_GIT_REF = /^[\\w./@^~{}\\-]+$/\nfunction assertSafeRef(ref: string): void {\n if (!SAFE_GIT_REF.test(ref)) {\n throw new Error(`Invalid git ref: \"${ref}\"`)\n }\n}\n\n/**\n * Execute a git command and return the output\n */\nasync function git(args: string, cwd: string = process.cwd()): Promise<string> {\n const { stdout } = await execAsync(`git ${args}`, { cwd, maxBuffer: 10 * 1024 * 1024 })\n return stdout.trim()\n}\n\n/**\n * Check if the current directory is a git repository\n */\nexport async function isGitRepo(cwd: string = process.cwd()): Promise<boolean> {\n try {\n await access(join(cwd, '.git'))\n return true\n } catch {\n try {\n await git('rev-parse --git-dir', cwd)\n return true\n } catch {\n return false\n }\n }\n}\n\n/**\n * Get the default branch name\n */\nexport async function getDefaultBranch(cwd: string = process.cwd()): Promise<string> {\n try {\n // Try to get from remote\n const remoteBranch = await git('symbolic-ref refs/remotes/origin/HEAD --short', cwd)\n return remoteBranch.replace('origin/', '')\n } catch {\n // Fallback to main or master\n try {\n await git('show-ref --verify refs/heads/main', cwd)\n return 'main'\n } catch {\n return 'master'\n }\n }\n}\n\n/**\n * Get the current branch name\n */\nexport async function getCurrentBranch(cwd: string = process.cwd()): Promise<string> {\n return git('branch --show-current', cwd)\n}\n\n/**\n * Get the remote repository URL\n */\nexport async function getRemoteUrl(cwd: string = process.cwd()): Promise<string | null> {\n try {\n const url = await git('remote get-url origin', cwd)\n return url\n } catch {\n return null\n }\n}\n\n/**\n * Parse remote URL to get owner/repo format\n */\nexport function parseRepoFromUrl(url: string): { owner: string; repo: string } | null {\n // Handle SSH URLs: git@github.com:owner/repo.git\n const sshMatch = url.match(/git@github\\.com:([^/]+)\\/([^/]+?)(?:\\.git)?$/)\n if (sshMatch) {\n return { owner: sshMatch[1]!, repo: sshMatch[2]! }\n }\n\n // Handle HTTPS URLs: https://github.com/owner/repo.git\n const httpsMatch = url.match(/https:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?$/)\n if (httpsMatch) {\n return { owner: httpsMatch[1]!, repo: httpsMatch[2]! }\n }\n\n return null\n}\n\n/**\n * Get all tags sorted by version\n */\nexport async function getTags(cwd: string = process.cwd()): Promise<string[]> {\n try {\n const output = await git('tag --sort=-version:refname', cwd)\n if (!output) return []\n return output.split('\\n').filter(Boolean)\n } catch {\n return []\n }\n}\n\n/**\n * Get the latest tag\n */\nexport async function getLatestTag(cwd: string = process.cwd()): Promise<string | null> {\n try {\n return await git('describe --tags --abbrev=0', cwd)\n } catch {\n return null\n }\n}\n\n/**\n * Get the tag before a given tag (for automatic --from detection).\n */\nexport async function getPreviousTag(\n tag: string,\n cwd: string = process.cwd()\n): Promise<string | null> {\n assertSafeRef(tag)\n try {\n return await git(`describe --tags --abbrev=0 ${tag}^`, cwd)\n } catch {\n return null\n }\n}\n\n/**\n * Get the root directory of the git repository.\n */\nexport async function getGitRoot(cwd: string = process.cwd()): Promise<string> {\n return git('rev-parse --show-toplevel', cwd)\n}\n\n/**\n * Check if the repo is a shallow clone.\n */\nexport async function isShallowClone(cwd: string = process.cwd()): Promise<boolean> {\n try {\n const result = await git('rev-parse --is-shallow-repository', cwd)\n return result === 'true'\n } catch {\n return false\n }\n}\n\nexport interface LocalCommitInfo {\n sha: string\n message: string\n author: string\n date: string\n}\n\n/**\n * Get commits between two refs, returning structured commit data.\n * Uses NUL bytes as separators (cannot appear in git commit data).\n */\nexport async function getCommitsBetween(\n from: string,\n to: string,\n cwd: string = process.cwd()\n): Promise<LocalCommitInfo[]> {\n assertSafeRef(from)\n assertSafeRef(to)\n\n // %x00%x01 = commit separator (NUL+SOH), %x00 = field separator (NUL)\n // Message (%B) is placed last since it can be multi-line\n const format = '%x00%x01%H%x00%an%x00%aI%x00%B'\n\n const output = await git(`log ${from}..${to} --format=\"${format}\" --no-merges`, cwd)\n if (!output) return []\n\n const commits: LocalCommitInfo[] = []\n const rawCommits = output.split('\\x00\\x01').filter(Boolean)\n\n for (const raw of rawCommits) {\n const parts = raw.split('\\x00')\n if (parts.length < 4) continue\n\n const sha = parts[0]!.trim()\n const author = parts[1]!.trim()\n const date = parts[2]!.trim()\n // Join remaining parts (message can't contain NUL, but be defensive)\n const message = parts.slice(3).join('\\x00').trim()\n\n if (sha) {\n commits.push({ sha, message, author, date })\n }\n }\n\n return commits\n}\n\nexport interface LocalDiffFileInfo {\n filename: string\n status: 'added' | 'modified' | 'deleted' | 'renamed' | 'copied'\n additions: number\n deletions: number\n patch: string\n}\n\nexport interface LocalCommitDiffInfo {\n sha: string\n files: LocalDiffFileInfo[]\n}\n\n/**\n * Get the diff for a single commit, including file stats and patch.\n * Uses a single git call for both numstat and patch output.\n */\nexport async function getCommitDiff(\n sha: string,\n cwd: string = process.cwd()\n): Promise<LocalCommitDiffInfo> {\n assertSafeRef(sha)\n\n // Single git call: numstat lines appear first, then the patch\n const output = await git(`show ${sha} --numstat -p --format=\"\"`, cwd)\n\n // Split output into numstat section and patch section\n const patchStart = output.search(/^diff --git /m)\n const numstatSection = patchStart !== -1 ? output.slice(0, patchStart) : output\n const patchSection = patchStart !== -1 ? output.slice(patchStart) : ''\n\n // Parse numstat lines: \"additions\\tdeletions\\tfilename\"\n const fileStats = new Map<string, { additions: number; deletions: number }>()\n for (const line of numstatSection.split('\\n').filter(Boolean)) {\n const match = line.match(/^(\\d+|-)\\t(\\d+|-)\\t(.+)$/)\n if (match) {\n const additions = match[1] === '-' ? 0 : parseInt(match[1]!, 10)\n const deletions = match[2] === '-' ? 0 : parseInt(match[2]!, 10)\n const filename = match[3]!\n // Skip binary files (indicated by - - in numstat)\n if (match[1] !== '-' || match[2] !== '-') {\n fileStats.set(filename, { additions, deletions })\n }\n }\n }\n\n // Split the patch by file\n const files: LocalDiffFileInfo[] = []\n const filePatchRegex = /^diff --git a\\/(.+?) b\\/(.+?)$/gm\n const patchParts: Array<{ filename: string; startIndex: number }> = []\n\n let match: RegExpExecArray | null\n while ((match = filePatchRegex.exec(patchSection)) !== null) {\n patchParts.push({ filename: match[2]!, startIndex: match.index })\n }\n\n for (let i = 0; i < patchParts.length; i++) {\n const part = patchParts[i]!\n const endIndex = i + 1 < patchParts.length ? patchParts[i + 1]!.startIndex : patchSection.length\n const filePatch = patchSection.substring(part.startIndex, endIndex).trim()\n const stats = fileStats.get(part.filename)\n\n // Skip binary files\n if (!stats) continue\n\n // Determine status from the diff header\n let status: LocalDiffFileInfo['status'] = 'modified'\n if (filePatch.includes('new file mode')) {\n status = 'added'\n } else if (filePatch.includes('deleted file mode')) {\n status = 'deleted'\n } else if (filePatch.includes('rename from')) {\n status = 'renamed'\n }\n\n files.push({\n filename: part.filename,\n status,\n additions: stats.additions,\n deletions: stats.deletions,\n patch: filePatch,\n })\n }\n\n return { sha, files }\n}\n\n/**\n * Derive a repo name from the current directory or remote URL.\n */\nexport async function deriveRepoName(cwd: string = process.cwd()): Promise<string> {\n // Try to get from remote URL\n const remoteUrl = await getRemoteUrl(cwd)\n if (remoteUrl) {\n // Try GitHub format first\n const ghInfo = parseRepoFromUrl(remoteUrl)\n if (ghInfo) {\n return `${ghInfo.owner}/${ghInfo.repo}`\n }\n // Try generic git URL parsing\n const genericMatch = remoteUrl.match(/[/:]([^/]+\\/[^/]+?)(?:\\.git)?$/)\n if (genericMatch) {\n return genericMatch[1]!\n }\n }\n // Fall back to directory name\n const { basename } = await import('node:path')\n return basename(cwd)\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport { writeFile } from 'node:fs/promises'\nimport { isLoggedIn, getApiUrl } from '../config.js'\nimport { isGitRepo, getRemoteUrl, parseRepoFromUrl, getLatestTag, getGitRoot } from '../git.js'\nimport { getRepoByName, startGeneration, getChangelog, ApiError } from '../api.js'\nimport { prependToChangelog } from '../changelog.js'\n\nconst POLL_INTERVAL_MS = 5_000\nconst POLL_TIMEOUT_MS = 10 * 60 * 1_000 // 10 minutes\n\nexport const githubCommand = new Command('github')\n .description('Generate a changelog via GitHub App (requires installation)')\n .argument('[version]', 'Version tag to generate changelog for (e.g., v1.0.0)')\n .option('--from <tag>', 'Starting tag/commit (defaults to previous tag)')\n .option('--to <ref>', 'Ending ref (defaults to the version tag)')\n .option('-o, --output <file>', 'Output file (defaults to stdout)')\n .option('-w, --write', 'Prepend to CHANGELOG.md')\n .action(async (version, options) => {\n // Require login\n if (!isLoggedIn()) {\n console.error(chalk.red('Error: Not logged in'))\n console.log(chalk.gray('Run `changesmith login` to authenticate.'))\n process.exit(1)\n }\n\n // Check if we're in a git repo\n if (!(await isGitRepo())) {\n console.error(chalk.red('Error: Not a git repository'))\n process.exit(1)\n }\n\n // Determine version\n let targetVersion = version\n if (!targetVersion) {\n const latestTag = await getLatestTag()\n if (latestTag) {\n targetVersion = latestTag\n console.log(chalk.gray(`Using latest tag: ${targetVersion}`))\n } else {\n console.error(chalk.red('Error: No version specified and no tags found'))\n console.log(chalk.gray('Usage: changesmith github v1.0.0 [-w] [-o file]'))\n process.exit(1)\n }\n }\n\n // Get repo info from git remote\n const remoteUrl = await getRemoteUrl()\n const repoInfo = remoteUrl ? parseRepoFromUrl(remoteUrl) : null\n\n if (!repoInfo) {\n console.error(chalk.red('Error: Could not determine repository from git remote'))\n console.log(chalk.gray('Make sure your repository has a GitHub remote configured.'))\n process.exit(1)\n }\n\n // Look up repo in Changesmith\n const repoSpinner = ora('Looking up repository...').start()\n let repoId: string\n try {\n const repo = await getRepoByName(repoInfo.owner, repoInfo.repo)\n repoId = repo.id\n repoSpinner.succeed(`Repository: ${chalk.cyan(repo.fullName)}`)\n } catch (error) {\n if (error instanceof ApiError && error.status === 404) {\n repoSpinner.fail('Repository not connected to Changesmith')\n const appUrl = deriveWebUrl(getApiUrl())\n console.log('')\n console.log('To connect this repository:')\n console.log(chalk.cyan(' 1. ') + `Visit ${chalk.underline(`${appUrl}/dashboard/repos`)}`)\n console.log(chalk.cyan(' 2. ') + 'Click \"Add Repository\" and install the GitHub App')\n console.log(chalk.cyan(' 3. ') + 'Select this repository for access')\n process.exit(1)\n }\n repoSpinner.fail('Failed to look up repository')\n console.error(chalk.red(error instanceof Error ? error.message : String(error)))\n process.exit(1)\n }\n\n // Start generation\n const genSpinner = ora('Starting changelog generation...').start()\n let changelogId: string\n try {\n const result = await startGeneration(repoId, {\n version: targetVersion,\n fromTag: options.from,\n toTag: options.to,\n })\n changelogId = result.changelogId\n genSpinner.succeed(`Generation queued (${result.fromTag} → ${targetVersion})`)\n } catch (error) {\n genSpinner.fail('Failed to start generation')\n console.error(chalk.red(error instanceof Error ? error.message : String(error)))\n process.exit(1)\n }\n\n // Resolve git root for CHANGELOG.md path\n const gitRoot = await getGitRoot()\n\n // Poll for completion\n const pollSpinner = ora('Generating changelog...').start()\n const startTime = Date.now()\n\n try {\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n const elapsed = Math.floor((Date.now() - startTime) / 1000)\n pollSpinner.text = `Generating changelog... (${elapsed}s)`\n\n await sleep(POLL_INTERVAL_MS)\n\n const changelog = await getChangelog(changelogId)\n\n if (changelog.status === 'draft' || changelog.status === 'approved') {\n pollSpinner.succeed('Changelog generated')\n\n // Output result\n if (options.write) {\n await prependToChangelog(changelog.content, targetVersion, gitRoot)\n console.log(chalk.green('CHANGELOG.md updated'))\n } else if (options.output) {\n await writeFile(options.output, changelog.content + '\\n', 'utf-8')\n console.log(chalk.green(`Changelog written to ${options.output}`))\n } else {\n console.log('')\n console.log(chalk.cyan('─'.repeat(60)))\n console.log(changelog.content)\n console.log(chalk.cyan('─'.repeat(60)))\n }\n return\n }\n\n if (changelog.status === 'failed') {\n const errorMsg =\n (changelog.metadata as Record<string, unknown> | null)?.errorMessage || 'Unknown error'\n pollSpinner.fail('Changelog generation failed')\n console.error(chalk.red(String(errorMsg)))\n process.exit(1)\n }\n\n if (changelog.status === 'published') {\n pollSpinner.succeed('Changelog already published')\n console.log(changelog.content)\n return\n }\n\n // Still 'generating' or 'publishing' — keep polling\n }\n\n pollSpinner.fail('Generation timed out')\n console.error(chalk.red('Changelog generation did not complete within 10 minutes.'))\n console.log(chalk.gray('Check the dashboard for status.'))\n process.exit(1)\n } catch (error) {\n pollSpinner.fail('Error while waiting for generation')\n console.error(chalk.red(error instanceof Error ? error.message : String(error)))\n process.exit(1)\n }\n })\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Derive the web app URL from an API URL.\n * Handles the api.{domain} convention and falls back to the API origin for\n * URLs that don't follow the pattern (e.g. localhost, custom domains).\n */\nexport function deriveWebUrl(apiUrlString: string): string {\n try {\n const apiUrl = new URL(apiUrlString)\n if (apiUrl.hostname.startsWith('api.')) {\n return `${apiUrl.protocol}//${apiUrl.hostname.slice(4)}`\n }\n // Localhost or custom domain — return origin as-is\n return apiUrl.origin\n } catch {\n return apiUrlString\n }\n}\n","import { getApiUrl, getAuthToken, isEnvAuth, warnIfEnvTokenSuspicious } from './config.js'\n\nclass ApiError extends Error {\n /** Structured error code from the API response JSON (e.g. 'expired_token', 'authorization_pending') */\n public code: string | undefined\n\n constructor(\n public status: number,\n message: string,\n code?: string\n ) {\n super(message)\n this.name = 'ApiError'\n this.code = code\n }\n}\n\nasync function request<T>(\n path: string,\n options: RequestInit = {},\n tokenOverride?: string\n): Promise<T> {\n const apiUrl = getApiUrl()\n warnIfEnvTokenSuspicious()\n const token = tokenOverride ?? getAuthToken()\n\n const headers: Record<string, string> = {\n ...((options.headers as Record<string, string>) || {}),\n }\n\n if (token) {\n headers['Authorization'] = `Bearer ${token}`\n }\n\n if (options.body && !headers['Content-Type']) {\n headers['Content-Type'] = 'application/json'\n }\n\n const response = await fetch(`${apiUrl}${path}`, {\n ...options,\n headers,\n })\n\n if (!response.ok) {\n switch (response.status) {\n case 401: {\n let message: string\n if (tokenOverride) {\n message = 'Not authenticated. The provided token may be invalid or expired.'\n } else if (isEnvAuth()) {\n message = 'Not authenticated. CHANGESMITH_TOKEN may be invalid or expired.'\n } else {\n message = 'Not authenticated. Run `changesmith login` to log in.'\n }\n throw new ApiError(401, message)\n }\n case 402:\n throw new ApiError(402, 'Usage limit reached. Upgrade your plan at changesmith.dev.')\n case 403: {\n let msg = 'CLI access requires a Business plan. Upgrade at changesmith.dev/dashboard/settings'\n try {\n const json = await response.json() as { message?: string }\n if (typeof json.message === 'string' && json.message.length > 0) {\n msg = json.message\n }\n } catch {\n // Response wasn't JSON — use default message\n }\n throw new ApiError(403, msg)\n }\n case 404:\n throw new ApiError(404, 'Not found.')\n default: {\n const text = await response.text().catch(() => response.statusText)\n let code: string | undefined\n let displayText = text\n try {\n const json = JSON.parse(text)\n if (typeof json === 'object' && json !== null) {\n // Prefer 'error' field (standard API format), fall back to 'code'\n if (typeof json.error === 'string' && json.error.length > 0) {\n code = json.error\n } else if (typeof json.code === 'string' && json.code.length > 0) {\n code = json.code\n }\n // Use the message field if available, otherwise the error code\n displayText =\n (typeof json.message === 'string' && json.message) ||\n (typeof json.error === 'string' && json.error) ||\n text\n }\n } catch {\n // Response wasn't JSON — code stays undefined\n }\n // Truncate and strip internal paths to avoid leaking server details\n if (displayText.length > 200) {\n displayText = displayText.substring(0, 200) + '...'\n }\n displayText = displayText.replace(/at [^\\s]+\\.(ts|js|mjs|cjs):\\d+/g, '[internal]')\n throw new ApiError(response.status, `API error (${response.status}): ${displayText}`, code)\n }\n }\n }\n\n return response.json() as Promise<T>\n}\n\nexport interface MeResponse {\n id: string\n githubId: number\n githubLogin: string\n email: string | null\n plan: string\n createdAt: string\n}\n\nexport interface RepoResponse {\n id: string\n githubId: number\n fullName: string\n defaultBranch: string\n settings: Record<string, unknown> | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface GenerateResponse {\n message: string\n jobId: string\n changelogId: string\n version: string\n fromTag: string\n}\n\nexport interface ChangelogResponse {\n id: string\n repoId: string\n repoFullName: string\n version: string\n status: 'generating' | 'draft' | 'approved' | 'published' | 'failed' | 'publishing'\n content: string\n metadata: Record<string, unknown> | null\n approvedBy: string | null\n approvedAt: string | null\n publishedAt: string | null\n releaseUrl: string | null\n createdAt: string\n updatedAt: string\n}\n\nexport interface DeviceAuthStartResponse {\n deviceCode: string\n userCode: string\n verificationUri: string\n expiresIn: number\n interval: number\n}\n\nexport interface DeviceAuthPollResponse {\n token: string\n}\n\nexport function getMe(token?: string): Promise<MeResponse> {\n return request<MeResponse>('/auth/me', {}, token)\n}\n\nexport function getRepoByName(owner: string, repo: string): Promise<RepoResponse> {\n return request<RepoResponse>(\n `/api/repos/by-name/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}`\n )\n}\n\nexport function startGeneration(\n repoId: string,\n body: { version: string; fromTag?: string; toTag?: string }\n): Promise<GenerateResponse> {\n return request<GenerateResponse>(`/api/repos/${repoId}/generate`, {\n method: 'POST',\n body: JSON.stringify(body),\n })\n}\n\nexport function getChangelog(changelogId: string): Promise<ChangelogResponse> {\n return request<ChangelogResponse>(`/api/changelogs/${changelogId}`)\n}\n\nexport function deviceAuthStart(): Promise<DeviceAuthStartResponse> {\n return request<DeviceAuthStartResponse>('/auth/device/start', {\n method: 'POST',\n })\n}\n\nexport function deviceAuthPoll(deviceCode: string): Promise<DeviceAuthPollResponse> {\n return request<DeviceAuthPollResponse>('/auth/device/poll', {\n method: 'POST',\n body: JSON.stringify({ deviceCode }),\n })\n}\n\nexport interface LocalGenerateRequest {\n version: string\n repoName: string\n commits: Array<{\n sha: string\n message: string\n author: string\n date: string\n }>\n diffs: Array<{\n sha: string\n files: Array<{\n filename: string\n status: 'added' | 'modified' | 'deleted' | 'renamed' | 'copied'\n additions: number\n deletions: number\n patch: string\n }>\n }>\n existingChangelog?: string\n customInstructions?: string\n}\n\nexport interface LocalGenerateStartResponse {\n message: string\n jobId: string\n}\n\nexport interface LocalGenerateResultResponse {\n status: 'pending' | 'completed' | 'error'\n content?: string\n error?: string\n}\n\nexport function startLocalGeneration(\n body: LocalGenerateRequest\n): Promise<LocalGenerateStartResponse> {\n return request<LocalGenerateStartResponse>('/api/generate/local', {\n method: 'POST',\n body: JSON.stringify(body),\n })\n}\n\nexport function getLocalGenerationResult(jobId: string): Promise<LocalGenerateResultResponse> {\n return request<LocalGenerateResultResponse>(\n `/api/generate/local/${encodeURIComponent(jobId)}`\n )\n}\n\nexport { ApiError }\n","import { readFile, writeFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { prependReleaseSection } from '@changesmith/core'\n\n/**\n * Prepend a new release section to CHANGELOG.md.\n * Creates the file if it doesn't exist.\n * @param rootDir - Root directory to resolve CHANGELOG.md relative to (defaults to cwd).\n */\nexport async function prependToChangelog(\n content: string,\n version: string,\n rootDir?: string\n): Promise<void> {\n const changelogPath = resolve(rootDir || process.cwd(), 'CHANGELOG.md')\n\n let existing: string | undefined\n try {\n existing = await readFile(changelogPath, 'utf-8')\n } catch {\n // No existing CHANGELOG.md\n }\n\n if (existing) {\n const updated = prependReleaseSection(existing, content, version)\n await writeFile(changelogPath, updated, 'utf-8')\n } else {\n await writeFile(changelogPath, `# Changelog\\n\\n${content}\\n`, 'utf-8')\n }\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport { readFile, writeFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { isLoggedIn } from '../config.js'\nimport type { LocalDiffFile, LocalCommitDiff } from '@changesmith/types'\nimport {\n isGitRepo,\n isShallowClone,\n getLatestTag,\n getPreviousTag,\n getCommitsBetween,\n getCommitDiff,\n deriveRepoName,\n getGitRoot,\n} from '../git.js'\nimport { readProjectConfig } from '../config.js'\nimport {\n startLocalGeneration,\n getLocalGenerationResult,\n ApiError,\n} from '../api.js'\nimport { prependToChangelog } from '../changelog.js'\n\nconst POLL_INTERVAL_MS = 3_000\nconst POLL_TIMEOUT_MS = 10 * 60 * 1_000 // 10 minutes\nconst MAX_TOTAL_DIFF_BYTES = 3 * 1024 * 1024 // 3MB (leaves ~1MB headroom for commits, metadata, and existingChangelog within the 4MB server limit)\nconst MAX_COMMITS = 500\n\nexport const localCommand = new Command('local')\n .description('Generate a changelog from local git commits (no GitHub App required)')\n .argument('[version]', 'Version tag to generate changelog for (e.g., v1.0.0)')\n .option('--from <ref>', 'Starting ref (defaults to the tag before version)')\n .option('--to <ref>', 'Ending ref (defaults to HEAD or the version tag)')\n .option('-o, --output <file>', 'Write output to a specific file')\n .option('-w, --write', 'Prepend to CHANGELOG.md')\n .action(async (version, options) => {\n // Require login\n if (!isLoggedIn()) {\n console.error(chalk.red('Error: Not logged in'))\n console.log(chalk.gray('Run `changesmith login` to authenticate.'))\n process.exit(1)\n }\n\n // Check if we're in a git repo\n if (!(await isGitRepo())) {\n console.error(chalk.red('Error: Not a git repository'))\n process.exit(1)\n }\n\n // Check for shallow clone — warn user that results may be incomplete\n if (await isShallowClone()) {\n console.error(chalk.yellow('Warning: This is a shallow clone. Commit history may be incomplete.'))\n console.log(chalk.gray('For full history, run: git fetch --unshallow'))\n }\n\n // Determine version\n let targetVersion = version\n if (!targetVersion) {\n const latestTag = await getLatestTag()\n if (latestTag) {\n targetVersion = latestTag\n console.log(chalk.gray(`Using latest tag: ${targetVersion}`))\n } else {\n console.error(chalk.red('Error: No version specified and no tags found'))\n console.log(chalk.gray('Usage: changesmith local v1.0.0'))\n console.log(chalk.gray(' or: changesmith local v1.0.0 --from HEAD~50'))\n process.exit(1)\n }\n }\n\n // Determine commit range\n const toRef = options.to || targetVersion\n let fromRef = options.from\n\n if (!fromRef) {\n // Try to find the previous tag\n const prevTag = await getPreviousTag(targetVersion)\n if (prevTag) {\n fromRef = prevTag\n console.log(chalk.gray(`Using previous tag as start: ${fromRef}`))\n } else {\n console.error(chalk.red('Error: No previous tag found.'))\n console.log(\n chalk.gray('Specify a starting ref with --from:')\n )\n console.log(chalk.gray(` changesmith local ${targetVersion} --from HEAD~50`))\n console.log(chalk.gray(` changesmith local ${targetVersion} --from abc1234`))\n process.exit(1)\n }\n }\n\n // Collect commits\n const commitSpinner = ora('Collecting commits...').start()\n let commits\n try {\n commits = await getCommitsBetween(fromRef, toRef)\n } catch (error) {\n commitSpinner.fail('Failed to collect commits')\n console.error(chalk.red(error instanceof Error ? error.message : String(error)))\n process.exit(1)\n }\n\n if (commits.length === 0) {\n commitSpinner.fail('No commits found in the specified range')\n console.log(chalk.gray(`Range: ${fromRef}..${toRef}`))\n process.exit(1)\n }\n\n if (commits.length > MAX_COMMITS) {\n commitSpinner.text = `Found ${commits.length} commits, using first ${MAX_COMMITS}`\n commits = commits.slice(0, MAX_COMMITS)\n }\n\n commitSpinner.succeed(`Found ${commits.length} commits (${fromRef}..${toRef})`)\n\n // Collect diffs with size cap\n const diffSpinner = ora('Collecting diffs...').start()\n const diffs: LocalCommitDiff[] = []\n let totalDiffBytes = 0\n let skippedDiffs = 0\n\n for (let i = 0; i < commits.length; i++) {\n const commit = commits[i]!\n diffSpinner.text = `Collecting diffs... (${i + 1}/${commits.length})`\n\n if (totalDiffBytes >= MAX_TOTAL_DIFF_BYTES) {\n skippedDiffs = commits.length - i\n break\n }\n\n try {\n const diff = await getCommitDiff(commit.sha)\n const diffSize = JSON.stringify(diff).length\n\n if (totalDiffBytes + diffSize > MAX_TOTAL_DIFF_BYTES) {\n skippedDiffs = commits.length - i\n break\n }\n\n diffs.push(diff)\n totalDiffBytes += diffSize\n } catch {\n // Skip commits where diff collection fails (e.g., initial commit)\n }\n }\n\n if (skippedDiffs > 0) {\n diffSpinner.succeed(\n `Collected diffs for ${diffs.length} commits (${skippedDiffs} skipped — 3MB limit)`\n )\n } else {\n diffSpinner.succeed(`Collected diffs for ${diffs.length} commits`)\n }\n\n // Resolve paths relative to git root (not cwd, which may be a subdirectory)\n const gitRoot = await getGitRoot()\n\n // Read existing CHANGELOG.md for style analysis\n let existingChangelog: string | undefined\n try {\n existingChangelog = await readFile(resolve(gitRoot, 'CHANGELOG.md'), 'utf-8')\n } catch {\n // No existing changelog — that's fine\n }\n\n // Read project config for custom instructions\n const projectConfig = await readProjectConfig()\n const customInstructions = projectConfig?.customPrompt\n\n // Derive repo name\n const repoName = await deriveRepoName()\n\n // Submit to API\n const genSpinner = ora('Starting changelog generation...').start()\n let jobId: string\n try {\n const result = await startLocalGeneration({\n version: targetVersion,\n repoName,\n commits,\n diffs,\n existingChangelog,\n customInstructions,\n })\n jobId = result.jobId\n genSpinner.succeed('Generation queued')\n } catch (error) {\n genSpinner.fail('Failed to start generation')\n if (error instanceof ApiError && error.status === 413) {\n console.error(chalk.red('Payload too large. Try a smaller commit range.'))\n } else {\n console.error(chalk.red(error instanceof Error ? error.message : String(error)))\n }\n process.exit(1)\n }\n\n // Poll for result\n const pollSpinner = ora('Generating changelog...').start()\n const startTime = Date.now()\n\n try {\n while (Date.now() - startTime < POLL_TIMEOUT_MS) {\n const elapsed = Math.floor((Date.now() - startTime) / 1000)\n pollSpinner.text = `Generating changelog... (${elapsed}s)`\n\n await sleep(POLL_INTERVAL_MS)\n\n const result = await getLocalGenerationResult(jobId)\n\n if (result.status === 'completed' && result.content) {\n pollSpinner.succeed('Changelog generated')\n\n // Handle output\n if (options.write) {\n await prependToChangelog(result.content, targetVersion, gitRoot)\n console.log(chalk.green('CHANGELOG.md updated'))\n } else if (options.output) {\n await writeFile(options.output, result.content + '\\n', 'utf-8')\n console.log(chalk.green(`Changelog written to ${options.output}`))\n } else {\n console.log('')\n console.log(chalk.cyan('─'.repeat(60)))\n console.log(result.content)\n console.log(chalk.cyan('─'.repeat(60)))\n }\n return\n }\n\n if (result.status === 'error') {\n pollSpinner.fail('Changelog generation failed')\n console.error(chalk.red(result.error || 'Unknown error'))\n process.exit(1)\n }\n\n // Still pending — keep polling\n }\n\n pollSpinner.fail('Generation timed out')\n console.error(chalk.red('Changelog generation did not complete within 10 minutes.'))\n process.exit(1)\n } catch (error) {\n pollSpinner.fail('Error while waiting for generation')\n console.error(chalk.red(error instanceof Error ? error.message : String(error)))\n process.exit(1)\n }\n })\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport ora from 'ora'\nimport {\n getApiUrl,\n setAuthToken,\n setUserId,\n isLoggedIn,\n isEnvAuth,\n MIN_TOKEN_LENGTH,\n MAX_TOKEN_LENGTH,\n} from '../config.js'\nimport { getMe, deviceAuthStart, deviceAuthPoll, ApiError } from '../api.js'\nconst MIN_POLL_INTERVAL_MS = 5000\nconst MAX_POLL_INTERVAL_MS = 60000\n\nexport const loginCommand = new Command('login')\n .description('Log in to Changesmith')\n .option('--token <token>', 'Use a pre-generated auth token (for CI/automation)')\n .action(async (options) => {\n // Handle direct token input\n if (options.token) {\n await validateAndSaveToken(options.token, { showEnvWarning: isEnvAuth() })\n return\n }\n\n // Check if authenticated via environment variable\n if (isEnvAuth()) {\n console.log(chalk.yellow('Already authenticated via CHANGESMITH_TOKEN environment variable.'))\n console.log(chalk.gray('Unset CHANGESMITH_TOKEN to use stored credentials instead.'))\n return\n }\n\n // Check if already logged in with stored credentials\n if (isLoggedIn()) {\n console.log(chalk.yellow('You are already logged in.'))\n console.log(chalk.gray('Run `changesmith logout` to log out first.'))\n return\n }\n\n // Start device auth flow\n await deviceAuthFlow()\n })\n\n/**\n * Validate and save a token\n */\nasync function validateAndSaveToken(\n token: string,\n opts: { showEnvWarning?: boolean } = {}\n): Promise<void> {\n const spinner = ora('Validating token...').start()\n\n try {\n // Validate length inside the try block so both format errors and API errors\n // follow the same code path, preventing timing side-channels.\n if (token.length < MIN_TOKEN_LENGTH || token.length > MAX_TOKEN_LENGTH) {\n throw new Error('Invalid token format.')\n }\n\n // Validate the token before persisting to disk\n const user = await getMe(token)\n setAuthToken(token)\n setUserId(user.id)\n if (opts.showEnvWarning) {\n spinner.succeed(\n `Token saved for ${chalk.cyan(user.githubLogin)}` +\n chalk.yellow(' (CHANGESMITH_TOKEN currently takes precedence)')\n )\n console.log(chalk.gray('Unset CHANGESMITH_TOKEN to use stored credentials.'))\n } else {\n spinner.succeed(`Logged in as ${chalk.cyan(user.githubLogin)}`)\n }\n } catch (error) {\n spinner.fail('Token validation failed')\n if (error instanceof ApiError) {\n console.error(chalk.red(error.message))\n } else if (error instanceof TypeError && error.message.includes('fetch')) {\n console.error(chalk.red('Unable to connect to API server. Check your network connection.'))\n } else if (error instanceof Error && error.name === 'AbortError') {\n console.error(chalk.red('Request timed out. The API server is not responding.'))\n } else if (error instanceof Error && error.message === 'Invalid token format.') {\n console.error(chalk.red(error.message))\n } else {\n console.error(chalk.red('Token validation failed. Please try again.'))\n }\n process.exit(1)\n }\n}\n\n/**\n * Run the device authorization flow\n */\nasync function deviceAuthFlow(): Promise<void> {\n const apiUrl = getApiUrl()\n\n console.log(chalk.cyan('Changesmith Login'))\n console.log('')\n\n // Start device auth\n const spinner = ora('Starting authentication...').start()\n\n try {\n const data = await deviceAuthStart()\n\n spinner.stop()\n\n // Show user code\n console.log('To authenticate, visit:')\n console.log('')\n console.log(chalk.cyan(` ${data.verificationUri}`))\n console.log('')\n console.log('And enter this code:')\n console.log('')\n console.log(chalk.bold.green(` ${data.userCode}`))\n console.log('')\n\n // Poll for completion\n const pollSpinner = ora('Waiting for authentication...').start()\n\n const token = await pollForToken(data.deviceCode, data.interval, data.expiresIn)\n\n if (!token) {\n pollSpinner.fail('Authentication timed out')\n process.exit(1)\n }\n\n // Validate token before persisting to disk\n try {\n const user = await getMe(token)\n setAuthToken(token)\n setUserId(user.id)\n pollSpinner.succeed(`Logged in as ${chalk.cyan(user.githubLogin)}`)\n } catch {\n // Token came from our own device auth flow, so persist even if /me fails\n // (e.g. transient network error after successful auth)\n setAuthToken(token)\n pollSpinner.succeed('Logged in')\n console.log(\n chalk.yellow(\n 'Warning: Could not verify token. If commands fail, try `changesmith logout` and log in again.'\n )\n )\n }\n\n console.log('')\n console.log('You can now generate changelogs:')\n console.log(chalk.gray(' changesmith generate v1.0.0'))\n } catch (error) {\n spinner.fail('Authentication failed')\n\n // If device auth isn't available, suggest manual token\n const appUrl = apiUrl.replace('/api', '').replace('api.', '')\n console.log('')\n console.log('To log in manually:')\n console.log(chalk.cyan(' 1. ') + `Visit ${appUrl}/dashboard/settings`)\n console.log(chalk.cyan(' 2. ') + 'Generate an API token')\n console.log(chalk.cyan(' 3. ') + 'Run: changesmith login --token YOUR_TOKEN')\n }\n}\n\n/**\n * Poll for the authentication token\n */\nasync function pollForToken(\n deviceCode: string,\n interval: number,\n expiresIn: number\n): Promise<string | null> {\n const pollInterval = Math.max(\n Math.min(interval * 1000, MAX_POLL_INTERVAL_MS),\n MIN_POLL_INTERVAL_MS\n )\n // Clamp expiresIn to a sane range (1 minute to 1 hour) to guard against\n // malformed or malicious server responses\n const safeExpiresIn = Math.max(60, Math.min(expiresIn, 3600))\n const maxAttempts = Math.floor((safeExpiresIn * 1000) / pollInterval)\n const startTime = Date.now()\n const absoluteTimeoutMs = safeExpiresIn * 1000\n\n for (let i = 0; i < maxAttempts; i++) {\n // Wall-clock timeout guard: stop polling if we've exceeded the server's expiry window,\n // accounting for clock skew and network delays.\n if (Date.now() - startTime >= absoluteTimeoutMs) {\n return null\n }\n await new Promise((resolve) => setTimeout(resolve, pollInterval))\n\n try {\n const data = await deviceAuthPoll(deviceCode)\n return data.token\n } catch (error) {\n if (error instanceof ApiError) {\n // ERR_DEVICE_002 = DEVICE_AUTHORIZATION_PENDING (defined in api/src/lib/error-codes.ts)\n if (error.code === 'ERR_DEVICE_002') {\n continue\n }\n // All other codes are terminal (expired_token, invalid_request, etc.)\n return null\n }\n // Network error, keep trying\n continue\n }\n }\n\n return null\n}\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport { clearAuth, isLoggedIn, isEnvAuth, hasStoredToken } from '../config.js'\n\nexport const logoutCommand = new Command('logout')\n .description('Log out from Changesmith cloud')\n .option('--clear-stored', 'Remove stored credentials (useful when CHANGESMITH_TOKEN is set)')\n .action(async (options) => {\n // Handle --clear-stored: remove stored credentials regardless of env auth\n if (options.clearStored) {\n if (hasStoredToken()) {\n clearAuth()\n console.log(chalk.green('Stored credentials cleared.'))\n } else {\n console.log(chalk.gray('No stored credentials to clear.'))\n }\n if (isEnvAuth()) {\n console.log(chalk.gray('Still authenticated via CHANGESMITH_TOKEN.'))\n }\n return\n }\n\n // Check if using environment variable auth\n if (isEnvAuth()) {\n console.log(chalk.yellow('Using CHANGESMITH_TOKEN environment variable.'))\n console.log(chalk.gray('Unset the environment variable to log out:'))\n console.log(chalk.gray(' unset CHANGESMITH_TOKEN'))\n if (hasStoredToken()) {\n console.log('')\n console.log(\n chalk.gray('Note: Stored credentials are preserved. Use --clear-stored to remove them.')\n )\n }\n return\n }\n\n if (!isLoggedIn()) {\n console.log(chalk.gray('You are not logged in.'))\n return\n }\n\n clearAuth()\n console.log(chalk.green('Logged out successfully.'))\n })\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport { isLoggedIn, isEnvAuth, projectConfigExists, readProjectConfig } from '../config.js'\nimport { isGitRepo, getRemoteUrl, parseRepoFromUrl, getLatestTag, getTags } from '../git.js'\nimport { getMe } from '../api.js'\n\nexport const statusCommand = new Command('status')\n .description('Show Changesmith status for the current repository')\n .action(async () => {\n console.log(chalk.cyan('Changesmith Status'))\n console.log('')\n\n // Git repository\n const isRepo = await isGitRepo()\n console.log(`Git repository: ${isRepo ? chalk.green('Yes') : chalk.red('No')}`)\n\n if (isRepo) {\n const remoteUrl = await getRemoteUrl()\n const repoInfo = remoteUrl ? parseRepoFromUrl(remoteUrl) : null\n if (repoInfo) {\n console.log(`Repository: ${chalk.white(`${repoInfo.owner}/${repoInfo.repo}`)}`)\n }\n\n const latestTag = await getLatestTag()\n const tags = await getTags()\n console.log(`Latest tag: ${latestTag ? chalk.white(latestTag) : chalk.gray('none')}`)\n console.log(`Total tags: ${chalk.white(tags.length.toString())}`)\n }\n\n console.log('')\n\n // Project config\n const hasConfig = await projectConfigExists()\n console.log(\n `Project config: ${hasConfig ? chalk.green('.changesmith.json') : chalk.gray('not initialized')}`\n )\n\n if (hasConfig) {\n const config = await readProjectConfig()\n if (config) {\n if (config.excludeTypes?.length) {\n console.log(`Excluded types: ${chalk.gray(config.excludeTypes.join(', '))}`)\n }\n if (config.customPrompt) {\n console.log(`Custom prompt: ${chalk.green('configured')}`)\n }\n }\n }\n\n console.log('')\n\n // Authentication\n const loggedIn = isLoggedIn()\n const envAuth = isEnvAuth()\n\n if (envAuth) {\n console.log(`Logged in: ${chalk.green('yes')} ${chalk.gray('(via CHANGESMITH_TOKEN)')}`)\n } else {\n console.log(`Logged in: ${loggedIn ? chalk.green('yes') : chalk.gray('no')}`)\n }\n\n if (loggedIn) {\n try {\n const user = await getMe()\n console.log(`User: ${chalk.white(user.githubLogin)}`)\n console.log(`Plan: ${chalk.white(user.plan)}`)\n } catch {\n // Ignore errors\n }\n }\n\n console.log('')\n\n // Quick help\n if (!hasConfig) {\n console.log(chalk.gray('Run `changesmith init` to initialize this repository.'))\n } else if (!loggedIn) {\n console.log(chalk.gray('Run `changesmith login` to authenticate.'))\n } else {\n console.log(chalk.gray('Run `changesmith generate` to create a changelog.'))\n }\n })\n","import { Command } from 'commander'\nimport chalk from 'chalk'\nimport {\n getApiUrl,\n setApiUrl,\n isLoggedIn,\n isEnvAuth,\n isEnvApiUrl,\n getUserId,\n readProjectConfig,\n writeProjectConfig,\n projectConfigExists,\n getProjectConfigPath,\n getDefaultProjectConfig,\n type ProjectConfig,\n} from '../config.js'\n\nexport const configCommand = new Command('config')\n .description('View or modify configuration')\n .addCommand(\n new Command('show')\n .description('Show current configuration')\n .option('--project', 'Show project config only')\n .option('--user', 'Show user config only')\n .action(async (options) => {\n if (!options.user) {\n await showProjectConfig()\n }\n if (!options.project) {\n showUserConfig()\n }\n })\n )\n .addCommand(\n new Command('set')\n .description('Set a configuration value')\n .argument('<key>', 'Config key to set')\n .argument('<value>', 'Value to set')\n .option('--global', 'Set in user config (default is project config)')\n .action(async (key, value, options) => {\n if (options.global) {\n setUserConfigValue(key, value)\n } else {\n await setProjectConfigValue(key, value)\n }\n })\n )\n .addCommand(\n new Command('get')\n .description('Get a configuration value')\n .argument('<key>', 'Config key to get')\n .option('--global', 'Get from user config (default is project config)')\n .action(async (key, options) => {\n if (options.global) {\n getUserConfigValue(key)\n } else {\n await getProjectConfigValue(key)\n }\n })\n )\n .addCommand(\n new Command('reset')\n .description('Reset project config to defaults')\n .option('-f, --force', 'Skip confirmation')\n .action(async (options) => {\n if (!(await projectConfigExists())) {\n console.log(chalk.yellow('No project config found.'))\n console.log(chalk.gray('Run `changesmith init` first.'))\n return\n }\n\n if (!options.force) {\n console.log(chalk.yellow('This will reset .changesmith.json to defaults.'))\n console.log(chalk.gray('Use --force to confirm.'))\n return\n }\n\n await writeProjectConfig(getDefaultProjectConfig())\n console.log(chalk.green('Project config reset to defaults.'))\n })\n )\n\n/**\n * Display the project configuration\n */\nasync function showProjectConfig(): Promise<void> {\n console.log(chalk.cyan('Project Configuration'))\n console.log(chalk.gray(` File: ${getProjectConfigPath()}`))\n console.log('')\n\n if (!(await projectConfigExists())) {\n console.log(chalk.gray(' No project config found.'))\n console.log(chalk.gray(' Run `changesmith init` to create one.'))\n console.log('')\n return\n }\n\n const config = await readProjectConfig()\n if (!config) {\n console.log(chalk.red(' Error reading config file.'))\n console.log('')\n return\n }\n\n console.log(chalk.white(' version: ') + config.version)\n if (config.defaultBranch) {\n console.log(chalk.white(' defaultBranch: ') + config.defaultBranch)\n }\n if (config.excludeTypes?.length) {\n console.log(chalk.white(' excludeTypes: ') + config.excludeTypes.join(', '))\n }\n if (config.includeScopes?.length) {\n console.log(chalk.white(' includeScopes: ') + config.includeScopes.join(', '))\n }\n if (config.excludeScopes?.length) {\n console.log(chalk.white(' excludeScopes: ') + config.excludeScopes.join(', '))\n }\n if (config.styleGuide) {\n console.log(chalk.white(' styleGuide: ') + config.styleGuide)\n }\n if (config.customPrompt) {\n console.log(chalk.white(' customPrompt: ') + chalk.green('(configured)'))\n }\n console.log('')\n}\n\n/**\n * Display user configuration\n */\nfunction showUserConfig(): void {\n console.log(chalk.cyan('User Configuration'))\n console.log('')\n if (isEnvApiUrl()) {\n console.log(chalk.white(' apiUrl: ') + getApiUrl() + chalk.gray(' (via env)'))\n } else {\n console.log(chalk.white(' apiUrl: ') + getApiUrl())\n }\n\n const loggedIn = isLoggedIn()\n const envAuth = isEnvAuth()\n if (envAuth) {\n console.log(chalk.white(' loggedIn: ') + chalk.green('yes') + chalk.gray(' (via env)'))\n } else {\n console.log(\n chalk.white(' loggedIn: ') + (loggedIn ? chalk.green('yes') : chalk.gray('no'))\n )\n }\n if (!envAuth && isLoggedIn()) {\n const userId = getUserId()\n if (userId) {\n console.log(chalk.white(' userId: ') + userId)\n }\n }\n console.log('')\n}\n\n/**\n * Set a user config value\n */\nfunction setUserConfigValue(key: string, value: string): void {\n switch (key) {\n case 'apiUrl':\n try {\n new URL(value)\n } catch {\n console.log(chalk.red(`Invalid URL: ${value}`))\n process.exit(1)\n }\n setApiUrl(value)\n console.log(chalk.green(`Set apiUrl to: ${value}`))\n break\n default:\n console.log(chalk.red(`Unknown user config key: ${key}`))\n console.log(chalk.gray('Available keys: apiUrl'))\n process.exit(1)\n }\n}\n\n/**\n * Get a user config value\n */\nfunction getUserConfigValue(key: string): void {\n switch (key) {\n case 'apiUrl':\n console.log(getApiUrl())\n break\n default:\n console.log(chalk.red(`Unknown user config key: ${key}`))\n console.log(chalk.gray('Available keys: apiUrl'))\n process.exit(1)\n }\n}\n\n/**\n * Set a project config value\n */\nasync function setProjectConfigValue(key: string, value: string): Promise<void> {\n if (!(await projectConfigExists())) {\n console.log(chalk.red('No project config found.'))\n console.log(chalk.gray('Run `changesmith init` first.'))\n process.exit(1)\n }\n\n const config = await readProjectConfig()\n if (!config) {\n console.log(chalk.red('Error reading config file.'))\n process.exit(1)\n }\n\n const validKeys = [\n 'defaultBranch',\n 'excludeTypes',\n 'includeScopes',\n 'excludeScopes',\n 'styleGuide',\n 'customPrompt',\n ]\n\n if (!validKeys.includes(key)) {\n console.log(chalk.red(`Unknown project config key: ${key}`))\n console.log(chalk.gray(`Available keys: ${validKeys.join(', ')}`))\n process.exit(1)\n }\n\n // Handle array values (comma-separated)\n const arrayKeys = ['excludeTypes', 'includeScopes', 'excludeScopes']\n if (arrayKeys.includes(key)) {\n const arrayValue = value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n const updatedConfig = { ...config, [key]: arrayValue }\n await writeProjectConfig(updatedConfig)\n console.log(chalk.green(`Set ${key} to: [${arrayValue.join(', ')}]`))\n } else {\n const updatedConfig = { ...config, [key]: value }\n await writeProjectConfig(updatedConfig)\n console.log(chalk.green(`Set ${key} to: ${value}`))\n }\n}\n\n/**\n * Get a project config value\n */\nasync function getProjectConfigValue(key: string): Promise<void> {\n const validKeys = [\n 'version',\n 'defaultBranch',\n 'excludeTypes',\n 'includeScopes',\n 'excludeScopes',\n 'styleGuide',\n 'customPrompt',\n ]\n\n if (!validKeys.includes(key)) {\n console.log(chalk.red(`Unknown project config key: ${key}`))\n console.log(chalk.gray(`Available keys: ${validKeys.join(', ')}`))\n process.exit(1)\n }\n\n if (!(await projectConfigExists())) {\n console.log(chalk.red('No project config found.'))\n process.exit(1)\n }\n\n const config = await readProjectConfig()\n if (!config) {\n console.log(chalk.red('Error reading config file.'))\n process.exit(1)\n }\n\n const configRecord = config as unknown as Record<string, unknown>\n const value = configRecord[key]\n\n if (value === undefined) {\n console.log(chalk.gray('(not set)'))\n } else if (Array.isArray(value)) {\n console.log(value.join(', '))\n } else {\n console.log(String(value))\n }\n}\n"],"mappings":"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","names":["Command","access","join","match","Command","chalk","ora","writeFile","readFile","writeFile","Command","chalk","ora","writeFile","resolve","Command","chalk","ora","readFile","writeFile","resolve","POLL_INTERVAL_MS","POLL_TIMEOUT_MS","Command","chalk","ora","readFile","resolve","sleep","writeFile","Command","chalk","ora","Command","chalk","ora","resolve","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@changesmith/cli",
|
|
3
|
+
"version": "1.4.0",
|
|
4
|
+
"description": "CLI for generating changelogs from git commits",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"changesmith": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsup",
|
|
16
|
+
"dev": "tsup --watch",
|
|
17
|
+
"typecheck": "tsc --noEmit",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"clean": "rm -rf dist"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@changesmith/core": "workspace:*",
|
|
23
|
+
"@changesmith/types": "workspace:*",
|
|
24
|
+
"chalk": "^5.3.0",
|
|
25
|
+
"commander": "^12.1.0",
|
|
26
|
+
"conf": "^13.0.0",
|
|
27
|
+
"ora": "^8.0.1"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@changesmith/tsconfig": "workspace:*",
|
|
31
|
+
"@types/node": "^22.19.10",
|
|
32
|
+
"tsup": "^8.0.2",
|
|
33
|
+
"typescript": "^5.7.3",
|
|
34
|
+
"vitest": "^2.1.9"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20"
|
|
38
|
+
}
|
|
39
|
+
}
|