Compare commits

...

10 Commits

Author SHA1 Message Date
366c4a0bc2 1.19.0
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-10-23 23:44:38 +00:00
0d3b10bd00 feat(mod_commit): Add CLI UI helpers and improve commit workflow with progress, recommendations and summary 2025-10-23 23:44:38 +00:00
a41e3d5d2c 1.18.9
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-10-23 18:24:13 +00:00
c45cff89de fix(mod_commit): Stage and commit deno.json when bumping/syncing versions and create/update git tags 2025-10-23 18:24:13 +00:00
7bb43ad478 1.18.8
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-10-23 18:18:09 +00:00
8dcaf1c631 fix(mod_commit): Improve commit workflow: detect project type and current branch; add robust version bump helpers for npm/deno 2025-10-23 18:18:08 +00:00
422761806d 1.18.7
Some checks failed
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 1s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-09-07 08:27:52 +00:00
31360240a9 fix(claude): Add .claude local settings to whitelist dev tool permissions 2025-09-07 08:27:52 +00:00
e338ee584f 1.18.6
Some checks failed
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 1s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-09-07 07:56:47 +00:00
31d2e18830 fix(deps): Bump dependency versions and add local Claude settings 2025-09-07 07:56:46 +00:00
7 changed files with 2183 additions and 3670 deletions

View File

@@ -1,5 +1,42 @@
# Changelog
## 2025-10-23 - 1.19.0 - feat(mod_commit)
Add CLI UI helpers and improve commit workflow with progress, recommendations and summary
- Introduce ts/mod_commit/mod.ui.ts: reusable CLI UI helpers (pretty headers, sections, AI recommendation box, step printer, commit summary and helpers for consistent messaging).
- Refactor ts/mod_commit/index.ts: use new UI functions to display AI recommendations, show step-by-step progress for baking commit info, generating changelog, staging, committing, bumping version and optional push; include commit SHA in final summary.
- Enhance ts/mod_commit/mod.helpers.ts: bumpProjectVersion now accepts currentStep/totalSteps to report progress and returns a consistent newVersion after handling npm/deno/both cases.
- Add .claude/settings.local.json: local permissions configuration for development tooling.
## 2025-10-23 - 1.18.9 - fix(mod_commit)
Stage and commit deno.json when bumping/syncing versions and create/update git tags
- bumpDenoVersion now creates a Smartshell instance and runs git add deno.json, git commit -m "v<newVersion>", and git tag v<newVersion> to persist the version bump
- syncVersionToDenoJson now stages deno.json, amends the npm version commit with --no-edit, and recreates the tag with -fa to keep package.json and deno.json in sync
- Added informative logger messages after creating commits and tags
## 2025-10-23 - 1.18.8 - fix(mod_commit)
Improve commit workflow: detect project type and current branch; add robust version bump helpers for npm/deno
- Add mod_commit/mod.helpers.ts with utilities: detectCurrentBranch(), detectProjectType(), bumpProjectVersion(), bumpDenoVersion(), bumpNpmVersion(), syncVersionToDenoJson(), and calculateNewVersion()
- Refactor ts/mod_commit/index.ts to use the new helpers: bumpProjectVersion(projectType, ... ) instead of a hard npm version call and push the actual current branch instead of hardcoding 'master'
- Support bumping versions for npm-only, deno-only, and hybrid (both) projects and synchronize versions from package.json to deno.json when applicable
- Improve branch detection with a fallback to 'master' and informative logging on detection failures
- Add local Claude settings file (.claude/settings.local.json) (editor/CI config) — no code behavior change but included in diff
## 2025-09-07 - 1.18.7 - fix(claude)
Add .claude local settings to whitelist dev tool permissions
- Add .claude/settings.local.json to configure allowed permissions for local AI/tooling helpers (Bash commands, WebFetch, and mcp_serena actions).
- Disable enableAllProjectMcpServers (set to false) to limit automatic project MCP server usage.
## 2025-09-07 - 1.18.6 - fix(deps)
Bump dependency versions and add local Claude settings
- Updated devDependencies: @git.zone/tsbuild ^2.6.4 → ^2.6.8, @git.zone/tstest ^2.3.4 → ^2.3.6, @push.rocks/smartfile ^11.2.5 → ^11.2.7
- Updated dependencies: @git.zone/tsdoc ^1.5.1 → ^1.5.2, @git.zone/tspublish ^1.10.1 → ^1.10.3, @push.rocks/smartlog ^3.1.8 → ^3.1.9, @push.rocks/smartnpm ^2.0.4 → ^2.0.6, @push.rocks/smartscaf ^4.0.17 → ^4.0.19
- Added .claude/settings.local.json to configure local Claude permissions/settings
## 2025-08-17 - 1.18.5 - fix(dependencies)
Bump smartshell and smartscaf versions; add .claude local settings

View File

@@ -1,7 +1,7 @@
{
"name": "@git.zone/cli",
"private": false,
"version": "1.18.5",
"version": "1.19.0",
"description": "A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.",
"main": "dist_ts/index.ts",
"typings": "dist_ts/index.d.ts",
@@ -57,19 +57,19 @@
},
"homepage": "https://gitlab.com/gitzone/private/gitzone#readme",
"devDependencies": {
"@git.zone/tsbuild": "^2.6.4",
"@git.zone/tsbuild": "^2.6.8",
"@git.zone/tsrun": "^1.3.3",
"@git.zone/tstest": "^2.3.4",
"@git.zone/tstest": "^2.3.6",
"@push.rocks/smartdelay": "^3.0.5",
"@push.rocks/smartfile": "^11.2.5",
"@push.rocks/smartfile": "^11.2.7",
"@push.rocks/smartinteract": "^2.0.16",
"@push.rocks/smartnetwork": "^4.1.2",
"@push.rocks/smartshell": "^3.3.0",
"@types/node": "^22.15.18"
},
"dependencies": {
"@git.zone/tsdoc": "^1.5.1",
"@git.zone/tspublish": "^1.10.1",
"@git.zone/tsdoc": "^1.5.2",
"@git.zone/tspublish": "^1.10.3",
"@push.rocks/commitinfo": "^1.0.12",
"@push.rocks/early": "^4.0.4",
"@push.rocks/gulp-function": "^3.0.7",
@@ -82,15 +82,15 @@
"@push.rocks/smartgulp": "^3.0.4",
"@push.rocks/smartjson": "^5.0.20",
"@push.rocks/smartlegal": "^1.0.27",
"@push.rocks/smartlog": "^3.1.8",
"@push.rocks/smartlog": "^3.1.9",
"@push.rocks/smartlog-destination-local": "^9.0.2",
"@push.rocks/smartmustache": "^3.0.2",
"@push.rocks/smartnpm": "^2.0.4",
"@push.rocks/smartnpm": "^2.0.6",
"@push.rocks/smartobject": "^1.0.12",
"@push.rocks/smartopen": "^2.0.0",
"@push.rocks/smartpath": "^6.0.0",
"@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smartscaf": "^4.0.17",
"@push.rocks/smartscaf": "^4.0.19",
"@push.rocks/smartstream": "^3.2.5",
"@push.rocks/smartunique": "^3.0.9",
"@push.rocks/smartupdate": "^2.0.6",

5264
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@git.zone/cli',
version: '1.18.5',
version: '1.19.0',
description: 'A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.'
}

View File

@@ -3,6 +3,8 @@
import * as plugins from './mod.plugins.js';
import * as paths from '../paths.js';
import { logger } from '../gitzone.logging.js';
import * as helpers from './mod.helpers.js';
import * as ui from './mod.ui.js';
export const run = async (argvArg: any) => {
if (argvArg.format) {
@@ -10,7 +12,8 @@ export const run = async (argvArg: any) => {
await formatMod.run();
}
logger.log('info', `gathering facts...`);
ui.printHeader('🔍 Analyzing repository changes...');
const aidoc = new plugins.tsdoc.AiDoc();
await aidoc.start();
@@ -18,16 +21,12 @@ export const run = async (argvArg: any) => {
await aidoc.stop();
logger.log(
'info',
`---------
Next recommended commit would be:
===========
-> ${nextCommitObject.recommendedNextVersion}:
-> ${nextCommitObject.recommendedNextVersionLevel}(${nextCommitObject.recommendedNextVersionScope}): ${nextCommitObject.recommendedNextVersionMessage}
===========
`,
);
ui.printRecommendation({
recommendedNextVersion: nextCommitObject.recommendedNextVersion,
recommendedNextVersionLevel: nextCommitObject.recommendedNextVersionLevel,
recommendedNextVersionScope: nextCommitObject.recommendedNextVersionScope,
recommendedNextVersionMessage: nextCommitObject.recommendedNextVersionMessage,
});
const commitInteract = new plugins.smartinteract.SmartInteract();
commitInteract.addQuestions([
{
@@ -69,20 +68,30 @@ export const run = async (argvArg: any) => {
}
})();
logger.log('info', `OK! Creating commit with message '${commitString}'`);
ui.printHeader('✨ Creating Semantic Commit');
ui.printCommitMessage(commitString);
const smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash',
sourceFilePaths: [],
});
logger.log('info', `Baking commitinfo into code ...`);
// Determine total steps (6 if pushing, 5 if not)
const totalSteps = answerBucket.getAnswerFor('pushToOrigin') && !(process.env.CI === 'true') ? 6 : 5;
let currentStep = 0;
// Step 1: Baking commitinfo
currentStep++;
ui.printStep(currentStep, totalSteps, '🔧 Baking commit info into code', 'in-progress');
const commitInfo = new plugins.commitinfo.CommitInfo(
paths.cwd,
commitVersionType,
);
await commitInfo.writeIntoPotentialDirs();
ui.printStep(currentStep, totalSteps, '🔧 Baking commit info into code', 'done');
logger.log('info', `Writing changelog.md ...`);
// Step 2: Writing changelog
currentStep++;
ui.printStep(currentStep, totalSteps, '📄 Generating changelog.md', 'in-progress');
let changelog = nextCommitObject.changelog;
changelog = changelog.replaceAll(
'{{nextVersion}}',
@@ -109,17 +118,54 @@ export const run = async (argvArg: any) => {
changelog,
plugins.path.join(paths.cwd, `changelog.md`),
);
ui.printStep(currentStep, totalSteps, '📄 Generating changelog.md', 'done');
logger.log('info', `Staging files for commit:`);
// Step 3: Staging files
currentStep++;
ui.printStep(currentStep, totalSteps, '📦 Staging files', 'in-progress');
await smartshellInstance.exec(`git add -A`);
ui.printStep(currentStep, totalSteps, '📦 Staging files', 'done');
// Step 4: Creating commit
currentStep++;
ui.printStep(currentStep, totalSteps, '💾 Creating git commit', 'in-progress');
await smartshellInstance.exec(`git commit -m "${commitString}"`);
await smartshellInstance.exec(`npm version ${commitVersionType}`);
ui.printStep(currentStep, totalSteps, '💾 Creating git commit', 'done');
// Step 5: Bumping version
currentStep++;
const projectType = await helpers.detectProjectType();
const newVersion = await helpers.bumpProjectVersion(projectType, commitVersionType, currentStep, totalSteps);
// Step 6: Push to remote (optional)
const currentBranch = await helpers.detectCurrentBranch();
if (
answerBucket.getAnswerFor('pushToOrigin') &&
!(process.env.CI === 'true')
) {
await smartshellInstance.exec(`git push origin master --follow-tags`);
currentStep++;
ui.printStep(currentStep, totalSteps, `🚀 Pushing to origin/${currentBranch}`, 'in-progress');
await smartshellInstance.exec(`git push origin ${currentBranch} --follow-tags`);
ui.printStep(currentStep, totalSteps, `🚀 Pushing to origin/${currentBranch}`, 'done');
}
console.log(''); // Add spacing before summary
// Get commit SHA for summary
const commitShaResult = await smartshellInstance.exec('git rev-parse --short HEAD');
const commitSha = commitShaResult.stdout.trim();
// Print final summary
ui.printSummary({
projectType,
branch: currentBranch,
commitType: answerBucket.getAnswerFor('commitType'),
commitScope: answerBucket.getAnswerFor('commitScope'),
commitMessage: answerBucket.getAnswerFor('commitDescription'),
newVersion: newVersion,
commitSha: commitSha,
pushed: answerBucket.getAnswerFor('pushToOrigin') && !(process.env.CI === 'true'),
});
};
const createCommitStringFromAnswerBucket = (

View File

@@ -0,0 +1,256 @@
import * as plugins from './mod.plugins.js';
import * as paths from '../paths.js';
import { logger } from '../gitzone.logging.js';
import * as ui from './mod.ui.js';
export type ProjectType = 'npm' | 'deno' | 'both' | 'none';
export type VersionType = 'patch' | 'minor' | 'major';
/**
* Detects the current git branch
* @returns The current branch name, defaults to 'master' if detection fails
*/
export async function detectCurrentBranch(): Promise<string> {
try {
const smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash',
sourceFilePaths: [],
});
const result = await smartshellInstance.exec('git branch --show-current');
const branchName = result.stdout.trim();
if (!branchName) {
logger.log('warn', 'Could not detect current branch, falling back to "master"');
return 'master';
}
logger.log('info', `Detected current branch: ${branchName}`);
return branchName;
} catch (error) {
logger.log('warn', `Failed to detect branch: ${error.message}, falling back to "master"`);
return 'master';
}
}
/**
* Detects the project type based on presence of package.json and/or deno.json
* @returns The project type
*/
export async function detectProjectType(): Promise<ProjectType> {
const packageJsonPath = plugins.path.join(paths.cwd, 'package.json');
const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json');
const hasPackageJson = await plugins.smartfile.fs.fileExists(packageJsonPath);
const hasDenoJson = await plugins.smartfile.fs.fileExists(denoJsonPath);
if (hasPackageJson && hasDenoJson) {
logger.log('info', 'Detected dual project (npm + deno)');
return 'both';
} else if (hasPackageJson) {
logger.log('info', 'Detected npm project');
return 'npm';
} else if (hasDenoJson) {
logger.log('info', 'Detected deno project');
return 'deno';
} else {
throw new Error('No package.json or deno.json found in current directory');
}
}
/**
* Parses a semantic version string and bumps it according to the version type
* @param currentVersion Current version string (e.g., "1.2.3")
* @param versionType Type of version bump
* @returns New version string
*/
function calculateNewVersion(currentVersion: string, versionType: VersionType): string {
const versionMatch = currentVersion.match(/^(\d+)\.(\d+)\.(\d+)/);
if (!versionMatch) {
throw new Error(`Invalid version format: ${currentVersion}`);
}
let [, major, minor, patch] = versionMatch.map(Number);
switch (versionType) {
case 'major':
major += 1;
minor = 0;
patch = 0;
break;
case 'minor':
minor += 1;
patch = 0;
break;
case 'patch':
patch += 1;
break;
}
return `${major}.${minor}.${patch}`;
}
/**
* Bumps the version in deno.json, commits the change, and creates a tag
* @param versionType Type of version bump
* @returns The new version string
*/
export async function bumpDenoVersion(versionType: VersionType): Promise<string> {
const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json');
const smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash',
sourceFilePaths: [],
});
try {
// Read deno.json
const denoConfig = plugins.smartfile.fs.toObjectSync(
denoJsonPath
) as { version?: string };
if (!denoConfig.version) {
throw new Error('deno.json does not contain a version field');
}
const currentVersion = denoConfig.version;
const newVersion = calculateNewVersion(currentVersion, versionType);
logger.log('info', `Bumping deno.json version: ${currentVersion}${newVersion}`);
// Update version
denoConfig.version = newVersion;
// Write back to disk
await plugins.smartfile.memory.toFs(
JSON.stringify(denoConfig, null, 2) + '\n',
denoJsonPath
);
// Stage the deno.json file
await smartshellInstance.exec('git add deno.json');
// Commit the version bump
await smartshellInstance.exec(`git commit -m "v${newVersion}"`);
// Create the version tag
await smartshellInstance.exec(`git tag v${newVersion} -m "v${newVersion}"`);
logger.log('info', `Created commit and tag v${newVersion}`);
return newVersion;
} catch (error) {
throw new Error(`Failed to bump deno.json version: ${error.message}`);
}
}
/**
* Bumps the version in package.json using npm version command
* @param versionType Type of version bump
* @returns The new version string
*/
async function bumpNpmVersion(versionType: VersionType): Promise<string> {
const smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash',
sourceFilePaths: [],
});
logger.log('info', `Bumping package.json version using npm version ${versionType}`);
const result = await smartshellInstance.exec(`npm version ${versionType}`);
// npm version returns the new version with a 'v' prefix, e.g., "v1.2.3"
const newVersion = result.stdout.trim().replace(/^v/, '');
return newVersion;
}
/**
* Syncs the version from package.json to deno.json and amends the npm commit
* @param version The version to sync
*/
async function syncVersionToDenoJson(version: string): Promise<void> {
const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json');
const smartshellInstance = new plugins.smartshell.Smartshell({
executor: 'bash',
sourceFilePaths: [],
});
try {
const denoConfig = plugins.smartfile.fs.toObjectSync(
denoJsonPath
) as { version?: string };
logger.log('info', `Syncing version to deno.json: ${version}`);
denoConfig.version = version;
await plugins.smartfile.memory.toFs(
JSON.stringify(denoConfig, null, 2) + '\n',
denoJsonPath
);
// Stage the deno.json file
await smartshellInstance.exec('git add deno.json');
// Amend the npm version commit to include deno.json
await smartshellInstance.exec('git commit --amend --no-edit');
// Re-create the tag with force to update it
await smartshellInstance.exec(`git tag -fa v${version} -m "v${version}"`);
logger.log('info', `Amended commit to include deno.json and updated tag v${version}`);
} catch (error) {
throw new Error(`Failed to sync version to deno.json: ${error.message}`);
}
}
/**
* Bumps the project version based on project type
* @param projectType The detected project type
* @param versionType The type of version bump
* @param currentStep The current step number for progress display
* @param totalSteps The total number of steps for progress display
* @returns The new version string
*/
export async function bumpProjectVersion(
projectType: ProjectType,
versionType: VersionType,
currentStep?: number,
totalSteps?: number
): Promise<string> {
const projectEmoji = projectType === 'npm' ? '📦' : projectType === 'deno' ? '🦕' : '🔀';
const description = `🏷️ Bumping version (${projectEmoji} ${projectType})`;
if (currentStep && totalSteps) {
ui.printStep(currentStep, totalSteps, description, 'in-progress');
}
let newVersion: string;
switch (projectType) {
case 'npm':
newVersion = await bumpNpmVersion(versionType);
break;
case 'deno':
newVersion = await bumpDenoVersion(versionType);
break;
case 'both': {
// Bump npm version first (it handles git tags)
newVersion = await bumpNpmVersion(versionType);
// Then sync to deno.json
await syncVersionToDenoJson(newVersion);
break;
}
case 'none':
throw new Error('Cannot bump version: no package.json or deno.json found');
default:
throw new Error(`Unknown project type: ${projectType}`);
}
if (currentStep && totalSteps) {
ui.printStep(currentStep, totalSteps, description, 'done');
}
return newVersion;
}

196
ts/mod_commit/mod.ui.ts Normal file
View File

@@ -0,0 +1,196 @@
import { logger } from '../gitzone.logging.js';
/**
* UI helper module for beautiful CLI output
*/
interface ICommitSummary {
projectType: string;
branch: string;
commitType: string;
commitScope: string;
commitMessage: string;
newVersion: string;
commitSha?: string;
pushed: boolean;
repoUrl?: string;
}
interface IRecommendation {
recommendedNextVersion: string;
recommendedNextVersionLevel: string;
recommendedNextVersionScope: string;
recommendedNextVersionMessage: string;
}
/**
* Print a header with a box around it
*/
export function printHeader(title: string): void {
const width = 57;
const padding = Math.max(0, width - title.length - 2);
const leftPad = Math.floor(padding / 2);
const rightPad = padding - leftPad;
console.log('');
console.log('╭─' + '─'.repeat(width) + '─╮');
console.log('│ ' + title + ' '.repeat(rightPad + leftPad) + ' │');
console.log('╰─' + '─'.repeat(width) + '─╯');
console.log('');
}
/**
* Print a section with a border
*/
export function printSection(title: string, lines: string[]): void {
const width = 59;
console.log('┌─ ' + title + ' ' + '─'.repeat(Math.max(0, width - title.length - 3)) + '┐');
console.log('│' + ' '.repeat(width) + '│');
for (const line of lines) {
const padding = width - line.length;
console.log('│ ' + line + ' '.repeat(Math.max(0, padding - 2)) + '│');
}
console.log('│' + ' '.repeat(width) + '│');
console.log('└─' + '─'.repeat(width) + '─┘');
console.log('');
}
/**
* Print AI recommendations in a nice box
*/
export function printRecommendation(recommendation: IRecommendation): void {
const lines = [
`Suggested Version: v${recommendation.recommendedNextVersion}`,
`Suggested Type: ${recommendation.recommendedNextVersionLevel}`,
`Suggested Scope: ${recommendation.recommendedNextVersionScope}`,
`Suggested Message: ${recommendation.recommendedNextVersionMessage}`,
];
printSection('📊 AI Recommendations', lines);
}
/**
* Print a progress step
*/
export function printStep(
current: number,
total: number,
description: string,
status: 'in-progress' | 'done' | 'error'
): void {
const statusIcon = status === 'done' ? '✓' : status === 'error' ? '✗' : '⏳';
const dots = '.'.repeat(Math.max(0, 40 - description.length));
console.log(` [${current}/${total}] ${description}${dots} ${statusIcon}`);
// Clear the line on next update if in progress
if (status === 'in-progress') {
process.stdout.write('\x1b[1A'); // Move cursor up one line
}
}
/**
* Get emoji for project type
*/
function getProjectTypeEmoji(projectType: string): string {
switch (projectType) {
case 'npm':
return '📦 npm';
case 'deno':
return '🦕 Deno';
case 'both':
return '🔀 npm + Deno';
default:
return '❓ Unknown';
}
}
/**
* Get emoji for commit type
*/
function getCommitTypeEmoji(commitType: string): string {
switch (commitType) {
case 'fix':
return '🔧 fix';
case 'feat':
return '✨ feat';
case 'BREAKING CHANGE':
return '💥 BREAKING CHANGE';
default:
return commitType;
}
}
/**
* Print final commit summary
*/
export function printSummary(summary: ICommitSummary): void {
const lines = [
`Project Type: ${getProjectTypeEmoji(summary.projectType)}`,
`Branch: 🌿 ${summary.branch}`,
`Commit Type: ${getCommitTypeEmoji(summary.commitType)}`,
`Scope: 📍 ${summary.commitScope}`,
`New Version: 🏷️ v${summary.newVersion}`,
];
if (summary.commitSha) {
lines.push(`Commit SHA: 📌 ${summary.commitSha}`);
}
if (summary.pushed) {
lines.push(`Remote: ✓ Pushed successfully`);
} else {
lines.push(`Remote: ⊘ Not pushed (local only)`);
}
if (summary.repoUrl && summary.commitSha) {
lines.push('');
lines.push(`View at: ${summary.repoUrl}/commit/${summary.commitSha}`);
}
printSection('✅ Commit Summary', lines);
if (summary.pushed) {
console.log('🎉 All done! Your changes are committed and pushed.\n');
} else {
console.log('✓ Commit created successfully.\n');
}
}
/**
* Print an info message with consistent formatting
*/
export function printInfo(message: string): void {
console.log(` ${message}`);
}
/**
* Print a success message
*/
export function printSuccess(message: string): void {
console.log(`${message}`);
}
/**
* Print a warning message
*/
export function printWarning(message: string): void {
logger.log('warn', `⚠️ ${message}`);
}
/**
* Print an error message
*/
export function printError(message: string): void {
logger.log('error', `${message}`);
}
/**
* Print commit message being created
*/
export function printCommitMessage(commitString: string): void {
console.log(`\n 📝 Commit: ${commitString}\n`);
}