gittable 1.0.8 → 1.0.9

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.
Files changed (36) hide show
  1. package/README.md +13 -313
  2. package/package.json +12 -9
  3. package/src/cli/interactive.js +65 -25
  4. package/src/commands/remote/push.js +27 -5
  5. package/src/commands/utilities/examples.js +2 -2
  6. package/src/commands/utilities/help.js +298 -9
  7. package/src/commands/utilities/index.js +5 -21
  8. package/src/commands/utilities/tag.js +195 -28
  9. package/src/commands/utilities/tutorial.js +784 -627
  10. package/src/core/config/setup.js +22 -13
  11. package/src/core/git/executor.js +2 -1
  12. package/src/ui/components/cli-table3/cell.js +410 -0
  13. package/src/ui/components/cli-table3/debug.js +29 -0
  14. package/src/ui/components/cli-table3/index.js +2 -0
  15. package/src/ui/components/cli-table3/layout-manager.js +255 -0
  16. package/src/ui/components/cli-table3/table.js +107 -0
  17. package/src/ui/components/cli-table3/utils.js +346 -0
  18. package/src/ui/components/index.js +5 -0
  19. package/src/ui/components/sisteransi.js +59 -0
  20. package/src/ui/components/spinner.js +459 -0
  21. package/src/ui/framework/layout.js +11 -14
  22. package/src/ui/framework/prompts.js +155 -155
  23. package/src/ui/framework/tables.js +1 -1
  24. package/src/ui/prompts/block.js +1 -1
  25. package/src/ui/prompts/core.js +1 -1
  26. package/src/ui/prompts/helpers.js +3 -9
  27. package/src/ui/prompts/index.js +1 -1
  28. package/src/ui/prompts/select.js +1 -1
  29. package/src/utils/commands/command-helpers.js +9 -0
  30. package/src/utils/table-sort.js +2 -7
  31. package/src/utils/ui/index.js +0 -1
  32. package/src/utils/ui/progress-indicator.js +2 -2
  33. package/src/utils/versions.js +1 -3
  34. package/src/ui/prompts/spinner.js +0 -116
  35. package/src/utils/ui/spinner.js +0 -57
  36. /package/src/ui/{ascii.js → components/ascii.js} +0 -0
package/README.md CHANGED
@@ -1,31 +1,18 @@
1
- # Gittable
1
+ <div align="center"><a name="readme-top"></a>
2
2
 
3
- <div align="center">
3
+ [![forthebadge](data:image/svg+xml;base64,PHN2ZyBkYXRhLXYtM2M4N2I3YjQ9IiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iOTIuMzg2Nzc2NzMzMzk4NDMiIGhlaWdodD0iMjQuNSIgdmlld0JveD0iMCAwIDEzMS45ODExMDk2MTkxNDA2MiAzNSIgY2xhc3M9ImJhZGdlLXN2ZyI+PGRlZnMgZGF0YS12LTNjODdiN2I0PSIiPjwhLS0tLT48IS0tLS0+PCEtLS0tPjwvZGVmcz48cGF0aCBkYXRhLXYtM2M4N2I3YjQ9IiIgZD0iTSA1IDAgTCA1MS45OTg0NjY0OTE2OTkyMiAwIEwgNTEuOTk4NDY2NDkxNjk5MjIgMzUgTCA1IDM1IFEgMCAzNSAwIDMwIEwgMCA1IFEgMCAwIDUgMCBaIiBmaWxsPSIjMzgzODM4Ii8+PHBhdGggZGF0YS12LTNjODdiN2I0PSIiIGQ9Ik0gNTEuOTk4NDY2NDkxNjk5MjIgMCBMIDEyNi45ODExMDk2MTkxNDA2MiAwIFEgMTMxLjk4MTEwOTYxOTE0MDYyIDAgMTMxLjk4MTEwOTYxOTE0MDYyIDUgTCAxMzEuOTgxMTA5NjE5MTQwNjIgMzAgUSAxMzEuOTgxMTA5NjE5MTQwNjIgMzUgMTI2Ljk4MTEwOTYxOTE0MDYyIDM1IEwgNTEuOTk4NDY2NDkxNjk5MjIgMzUgWiIgZmlsbD0iI2NiMzgzNyIvPjwhLS0tLT48dGV4dCBkYXRhLXYtM2M4N2I3YjQ9IiIgeD0iMjUuOTk5MjMzMjQ1ODQ5NjEiIHk9IjE3LjUiIGR5PSIwLjM1ZW0iIGZvbnQtc2l6ZT0iMTIiIGZvbnQtZmFtaWx5PSJNb250c2VycmF0LCBzYW5zLXNlcmlmIiBmaWxsPSIjRkZGRkZGIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBsZXR0ZXItc3BhY2luZz0iMiIgZm9udC13ZWlnaHQ9IjYwMCIgZm9udC1zdHlsZT0ibm9ybWFsIiB0ZXh0LWRlY29yYXRpb249Im5vbmUiIGZpbGwtb3BhY2l0eT0iMSIgZm9udC12YXJpYW50PSJub3JtYWwiIHN0eWxlPSJ0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOyI+UEtHPC90ZXh0PjxnIGRhdGEtdi0zYzg3YjdiND0iIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg2MS45OTg0NjY0OTE2OTkyMiwgOS41KSBzY2FsZSgwLjY2NjY2NjY2NjY2NjY2NjYpIj48cGF0aCBkYXRhLXYtM2M4N2I3YjQ9IiIgZD0iTTEuNzYzIDBDLjc4NiAwIDAgLjc4NiAwIDEuNzYzdjIwLjQ3NEMwIDIzLjIxNC43ODYgMjQgMS43NjMgMjRoMjAuNDc0Yy45NzcgMCAxLjc2My0uNzg2IDEuNzYzLTEuNzYzVjEuNzYzQzI0IC43ODYgMjMuMjE0IDAgMjIuMjM3IDB6TTUuMTMgNS4zMjNsMTMuODM3LjAxOS0uMDA5IDEzLjgzNmgtMy40NjRsLjAxLTEwLjM4MmgtMy40NTZMMTIuMDQgMTkuMTdINS4xMTN6IiBmaWxsPSIjZmZmZmZmIi8+PC9nPjx0ZXh0IGRhdGEtdi0zYzg3YjdiND0iIiB4PSIxMDEuOTg5Nzg4MDU1NDE5OTIiIHk9IjE3LjUiIGR5PSIwLjM1ZW0iIGZvbnQtc2l6ZT0iMTIiIGZvbnQtZmFtaWx5PSJNb250c2VycmF0LCBzYW5zLXNlcmlmIiBmaWxsPSIjZmZmZmZmIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBmb250LXdlaWdodD0iOTAwIiBsZXR0ZXItc3BhY2luZz0iMiIgZm9udC1zdHlsZT0ibm9ybWFsIiB0ZXh0LWRlY29yYXRpb249Im5vbmUiIGZpbGwtb3BhY2l0eT0iMSIgZm9udC12YXJpYW50PSJub3JtYWwiIHN0eWxlPSJ0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOyI+TlBNPC90ZXh0PjwhLS0tLT48L3N2Zz4=)](https://www.npmjs.com/package/gittable)
4
+ [![forthebadge](data:image/svg+xml;base64,PHN2ZyBkYXRhLXYtM2M4N2I3YjQ9IiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTQ4LjAyNzY2MzA0MDE2MTEyIiBoZWlnaHQ9IjI0LjUiIHZpZXdCb3g9IjAgMCAyMTEuNDY4MDkwMDU3MzczMDUgMzUiIGNsYXNzPSJiYWRnZS1zdmciPjxkZWZzIGRhdGEtdi0zYzg3YjdiND0iIj48IS0tLS0+PCEtLS0tPjwhLS0tLT48L2RlZnM+PHBhdGggZGF0YS12LTNjODdiN2I0PSIiIGQ9Ik0gNSAwIEwgNjIuNjY0NjIzMjYwNDk4MDUgMCBMIDYyLjY2NDYyMzI2MDQ5ODA1IDM1IEwgNSAzNSBRIDAgMzUgMCAzMCBMIDAgNSBRIDAgMCA1IDAgWiIgZmlsbD0iIzM4MzgzOCIvPjxwYXRoIGRhdGEtdi0zYzg3YjdiND0iIiBkPSJNIDYyLjY2NDYyMzI2MDQ5ODA1IDAgTCAyMDYuNDY4MDkwMDU3MzczMDUgMCBRIDIxMS40NjgwOTAwNTczNzMwNSAwIDIxMS40NjgwOTAwNTczNzMwNSA1IEwgMjExLjQ2ODA5MDA1NzM3MzA1IDMwIFEgMjExLjQ2ODA5MDA1NzM3MzA1IDM1IDIwNi40NjgwOTAwNTczNzMwNSAzNSBMIDYyLjY2NDYyMzI2MDQ5ODA1IDM1IFoiIGZpbGw9IiNmZmJiMDAiLz48IS0tLS0+PHRleHQgZGF0YS12LTNjODdiN2I0PSIiIHg9IjMxLjMzMjMxMTYzMDI0OTAyMyIgeT0iMTcuNSIgZHk9IjAuMzVlbSIgZm9udC1zaXplPSIxMiIgZm9udC1mYW1pbHk9Ik1vbnRzZXJyYXQsIHNhbnMtc2VyaWYiIGZpbGw9IiNGRkZGRkYiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGxldHRlci1zcGFjaW5nPSIyIiBmb250LXdlaWdodD0iNjAwIiBmb250LXN0eWxlPSJub3JtYWwiIHRleHQtZGVjb3JhdGlvbj0ibm9uZSIgZmlsbC1vcGFjaXR5PSIxIiBmb250LXZhcmlhbnQ9Im5vcm1hbCIgc3R5bGU9InRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7Ij5DT0RFPC90ZXh0PjxnIGRhdGEtdi0zYzg3YjdiND0iIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg3Mi42NjQ2MjMyNjA0OTgwNSwgOS41KSBzY2FsZSgwLjY2NjY2NjY2NjY2NjY2NjYpIj48cGF0aCBkYXRhLXYtM2M4N2I3YjQ9IiIgZD0iTTAgMGgyNHYyNEgwVjB6bTIyLjAzNCAxOC4yNzZjLS4xNzUtMS4wOTUtLjg4OC0yLjAxNS0zLjAwMy0yLjg3My0uNzM2LS4zNDUtMS41NTQtLjU4NS0xLjc5Ny0xLjE0LS4wOTEtLjMzLS4xMDUtLjUxLS4wNDYtLjcwNS4xNS0uNjQ2LjkxNS0uODQgMS41MTUtLjY2LjM5LjEyLjc1LjQyLjk3Ni45IDEuMDM0LS42NzYgMS4wMzQtLjY3NiAxLjc1NS0xLjEyNS0uMjctLjQyLS40MDQtLjYwMS0uNTg2LS43OC0uNjMtLjcwNS0xLjQ2OS0xLjA2NS0yLjgzNC0xLjAzNGwtLjcwNS4wODljLS42NzYuMTY1LTEuMzIuNTI1LTEuNzEgMS4wMDUtMS4xNCAxLjI5MS0uODExIDMuNTQxLjU2OSA0LjQ3MSAxLjM2NSAxLjAyIDMuMzYxIDEuMjQ0IDMuNjE2IDIuMjA1LjI0IDEuMTctLjg3IDEuNTQ1LTEuOTY2IDEuNDEtLjgxMS0uMTgtMS4yNi0uNTg2LTEuNzU1LTEuMzM2bC0xLjgzIDEuMDUxYy4yMS40OC40NS42ODkuODEgMS4xMDkgMS43NCAxLjc1NiA2LjA5IDEuNjY2IDYuODcxLTEuMDA0LjAyOS0uMDkuMjQtLjcwNS4wNzQtMS42NWwuMDQ2LjA2N3ptLTguOTgzLTcuMjQ1aC0yLjI0OGMwIDEuOTM4LS4wMDkgMy44NjQtLjAwOSA1LjgwNSAwIDEuMjMyLjA2MyAyLjM2My0uMTM4IDIuNzExLS4zMy42ODktMS4xOC42MDEtMS41NjYuNDgtLjM5Ni0uMTk2LS41OTctLjQ2Ni0uODMtLjg1NS0uMDYzLS4xMDUtLjExLS4xOTYtLjEyNy0uMTk2bC0xLjgyNSAxLjEyNWMuMzA1LjYzLjc1IDEuMTcyIDEuMzI0IDEuNTE3Ljg1NS41MSAyLjAwNC42NzUgMy4yMDcuNDA1Ljc4My0uMjI2IDEuNDU4LS42OTEgMS44MTEtMS40MTEuNTEtLjkzLjQwMi0yLjA3LjM5Ny0zLjM0Ni4wMTItMi4wNTQgMC00LjEwOSAwLTYuMTc5bC4wMDQtLjA1NnoiIGZpbGw9IiMzODM4MzgiLz48L2c+PHRleHQgZGF0YS12LTNjODdiN2I0PSIiIHg9IjE0Ny4wNjYzNTY2NTg5MzU1NSIgeT0iMTcuNSIgZHk9IjAuMzVlbSIgZm9udC1zaXplPSIxMiIgZm9udC1mYW1pbHk9Ik1vbnRzZXJyYXQsIHNhbnMtc2VyaWYiIGZpbGw9IiMzODM4MzgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZvbnQtd2VpZ2h0PSI5MDAiIGxldHRlci1zcGFjaW5nPSIyIiBmb250LXN0eWxlPSJub3JtYWwiIHRleHQtZGVjb3JhdGlvbj0ibm9uZSIgZmlsbC1vcGFjaXR5PSIxIiBmb250LXZhcmlhbnQ9Im5vcm1hbCIgc3R5bGU9InRleHQtdHJhbnNmb3JtOiB1cHBlcmNhc2U7Ij5KQVZBU0NSSVBUPC90ZXh0PjwhLS0tLT48L3N2Zz4=)](https://github.com/GG-Santos/Gittable)
5
+ [![forthebadge](data:image/svg+xml;base64,PHN2ZyBkYXRhLXYtM2M4N2I3YjQ9IiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iMTE5LjQ1MDU4NDQxMTYyMTA4IiBoZWlnaHQ9IjI0LjUiIHZpZXdCb3g9IjAgMCAxNzAuNjQzNjkyMDE2NjAxNTYgMzUiIGNsYXNzPSJiYWRnZS1zdmciPjxkZWZzIGRhdGEtdi0zYzg3YjdiND0iIj48IS0tLS0+PCEtLS0tPjwhLS0tLT48L2RlZnM+PHBhdGggZGF0YS12LTNjODdiN2I0PSIiIGQ9Ik0gNSAwIEwgNjIuMDAzNTcwNTU2NjQwNjI1IDAgTCA2Mi4wMDM1NzA1NTY2NDA2MjUgMzUgTCA1IDM1IFEgMCAzNSAwIDMwIEwgMCA1IFEgMCAwIDUgMCBaIiBmaWxsPSIjMzgzODM4Ii8+PHBhdGggZGF0YS12LTNjODdiN2I0PSIiIGQ9Ik0gNjIuMDAzNTcwNTU2NjQwNjI1IDAgTCAxNjUuNjQzNjkyMDE2NjAxNTYgMCBRIDE3MC42NDM2OTIwMTY2MDE1NiAwIDE3MC42NDM2OTIwMTY2MDE1NiA1IEwgMTcwLjY0MzY5MjAxNjYwMTU2IDMwIFEgMTcwLjY0MzY5MjAxNjYwMTU2IDM1IDE2NS42NDM2OTIwMTY2MDE1NiAzNSBMIDYyLjAwMzU3MDU1NjY0MDYyNSAzNSBaIiBmaWxsPSIjZTY1YzAwIi8+PCEtLS0tPjx0ZXh0IGRhdGEtdi0zYzg3YjdiND0iIiB4PSIzMS4wMDE3ODUyNzgzMjAzMTIiIHk9IjE3LjUiIGR5PSIwLjM1ZW0iIGZvbnQtc2l6ZT0iMTIiIGZvbnQtZmFtaWx5PSJNb250c2VycmF0LCBzYW5zLXNlcmlmIiBmaWxsPSIjRkZGRkZGIiB0ZXh0LWFuY2hvcj0ibWlkZGxlIiBsZXR0ZXItc3BhY2luZz0iMiIgZm9udC13ZWlnaHQ9IjYwMCIgZm9udC1zdHlsZT0ibm9ybWFsIiB0ZXh0LWRlY29yYXRpb249Im5vbmUiIGZpbGwtb3BhY2l0eT0iMSIgZm9udC12YXJpYW50PSJub3JtYWwiIHN0eWxlPSJ0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlOyI+UkVQTzwvdGV4dD48ZyBkYXRhLXYtM2M4N2I3YjQ9IiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNzIuMDAzNTcwNTU2NjQwNjIsIDkuNSkgc2NhbGUoMC42NjY2NjY2NjY2NjY2NjY2KSI+PHBhdGggZGF0YS12LTNjODdiN2I0PSIiIGQ9Ik0xMiAuMjk3Yy02LjYzIDAtMTIgNS4zNzMtMTIgMTIgMCA1LjMwMyAzLjQzOCA5LjggOC4yMDUgMTEuMzg1LjYuMTEzLjgyLS4yNTguODItLjU3NyAwLS4yODUtLjAxLTEuMDQtLjAxNS0yLjA0LTMuMzM4LjcyNC00LjA0Mi0xLjYxLTQuMDQyLTEuNjFDNC40MjIgMTguMDcgMy42MzMgMTcuNyAzLjYzMyAxNy43Yy0xLjA4Ny0uNzQ0LjA4NC0uNzI5LjA4NC0uNzI5IDEuMjA1LjA4NCAxLjgzOCAxLjIzNiAxLjgzOCAxLjIzNiAxLjA3IDEuODM1IDIuODA5IDEuMzA1IDMuNDk1Ljk5OC4xMDgtLjc3Ni40MTctMS4zMDUuNzYtMS42MDUtMi42NjUtLjMtNS40NjYtMS4zMzItNS40NjYtNS45MyAwLTEuMzEuNDY1LTIuMzggMS4yMzUtMy4yMi0uMTM1LS4zMDMtLjU0LTEuNTIzLjEwNS0zLjE3NiAwIDAgMS4wMDUtLjMyMiAzLjMgMS4yMy45Ni0uMjY3IDEuOTgtLjM5OSAzLS40MDUgMS4wMi4wMDYgMi4wNC4xMzggMyAuNDA1IDIuMjgtMS41NTIgMy4yODUtMS4yMyAzLjI4NS0xLjIzLjY0NSAxLjY1My4yNCAyLjg3My4xMiAzLjE3Ni43NjUuODQgMS4yMyAxLjkxIDEuMjMgMy4yMiAwIDQuNjEtMi44MDUgNS42MjUtNS40NzUgNS45Mi40Mi4zNi44MSAxLjA5Ni44MSAyLjIyIDAgMS42MDYtLjAxNSAyLjg5Ni0uMDE1IDMuMjg2IDAgLjMxNS4yMS42OS44MjUuNTdDMjAuNTY1IDIyLjA5MiAyNCAxNy41OTIgMjQgMTIuMjk3YzAtNi42MjctNS4zNzMtMTItMTItMTIiIGZpbGw9IiNmZmZmZmYiLz48L2c+PHRleHQgZGF0YS12LTNjODdiN2I0PSIiIHg9IjEyNi4zMjM2MzEyODY2MjExIiB5PSIxNy41IiBkeT0iMC4zNWVtIiBmb250LXNpemU9IjEyIiBmb250LWZhbWlseT0iTW9udHNlcnJhdCwgc2Fucy1zZXJpZiIgZmlsbD0iI2ZmZmZmZiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC13ZWlnaHQ9IjkwMCIgbGV0dGVyLXNwYWNpbmc9IjIiIGZvbnQtc3R5bGU9Im5vcm1hbCIgdGV4dC1kZWNvcmF0aW9uPSJub25lIiBmaWxsLW9wYWNpdHk9IjEiIGZvbnQtdmFyaWFudD0ibm9ybWFsIiBzdHlsZT0idGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTsiPkdJVEhVQjwvdGV4dD48IS0tLS0+PC9zdmc+)](https://github.com/GG-Santos/Gittable)
4
6
 
5
- **A modern, interactive Git CLI wrapper with conventional commits**
6
7
 
7
- [![forthebadge](https://img.shields.io/badge/NPM-PUBLISHED-ff4d4d?style=for-the-badge&logo=npm&logoColor=white)](https://www.npmjs.com/package/gittable)
8
- [![forthebadge](https://img.shields.io/badge/MADE%20WITH-JAVASCRIPT-ff4d4d?style=for-the-badge&logo=javascript&logoColor=white)](https://www.npmjs.com/package/gittable)
9
- [![forthebadge](https://img.shields.io/badge/BUILT%20FOR-DEVELOPERS-ff4d4d?style=for-the-badge&logo=git&logoColor=white)](https://github.com/GG-Santos/Gittable)
10
-
11
- [Installation](#installation) • [Quick Start](#quick-start) • [Documentation](#documentation) • [Architecture](./ARCHITECTURE.md)
8
+ <div align="justify">
9
+ Gittable is a modern, interactive suite built on top of Git operations, designed to improve developer productivity and make everyday Git workflows more intuitive. Rather than replacing Git, Gittable wraps standard Git commands in a beautiful, guided CLI experience that helps developers work faster, safer, and with more confidence—while remaining fully compatible with existing repositories and workflows. </br></br>
12
10
 
11
+ Every interaction is designed to reduce friction and prevent mistakes before they happen. For example, when committing with Gittable, you’re guided through required commit fields at commit time, with instant feedback on formatting and conventions. No more failed commits from late-running hooks, and no more hunting through CONTRIBUTING.md to figure out the correct message format. This same philosophy extends across the full Gittable workflow: proactive guidance, clear feedback, and smarter defaults that help teams stay consistent without slowing down. </br></br>
13
12
  </div>
14
13
 
15
- ---
16
-
17
- Gittable is a modern, interactive Git CLI wrapper that enhances the standard Git experience with beautiful prompts, conventional commits enforcement, and intelligent workflow suggestions. It provides a user-friendly interface for common Git operations while maintaining full compatibility with standard Git commands.
18
-
19
- ## ✨ Features
20
-
21
- - **🎨 Beautiful CLI Interface** - Native prompt system with colorful banners, tables, and status displays
22
- - **📝 Conventional Commits** - Enforces conventional commit message format for better project history
23
- - **⚡ Workflow Shortcuts** - Combined commands like `quick` (add+commit+push), `commit-push`, `add-commit`
24
- - **🧠 Smart Suggestions** - Context-aware next-step prompts after each command
25
- - **🛡️ Safety Features** - Branch protection warnings, backup before destructive operations
26
- - **🔧 Fully Configurable** - Customize commit types, scopes, and command behavior
27
- - **📚 Interactive Tutorial** - Learn Git workflows with guided tutorials
28
- - **🚀 Fast & Lightweight** - Minimal dependencies, maximum performance
14
+ </div>
15
+ <div align="left">
29
16
 
30
17
  ## 📦 Installation
31
18
 
@@ -47,291 +34,15 @@ npm install --save-dev gittable
47
34
  npx gittable <command>
48
35
  ```
49
36
 
50
- For detailed installation instructions, see the [Installation](#installation) section below.
51
-
52
- ## 🚀 Quick Start
53
-
54
- ### Interactive Mode
55
-
56
37
  Simply run `gittable` without any arguments to enter interactive mode:
57
38
 
58
39
  ```bash
59
- gittable
40
+ npx gittable
60
41
  ```
61
42
 
62
43
  This displays a beautiful category-based menu for easy command discovery.
63
44
 
64
- ### Command Mode
65
-
66
- Use Gittable just like Git, but with enhanced prompts:
67
-
68
- ```bash
69
- # Check repository status
70
- gittable status
71
- gittable st
72
-
73
- # Create a commit with conventional format
74
- gittable commit
75
- gittable ci
76
-
77
- # Branch management
78
- gittable branch
79
- gittable br
80
-
81
- # Quick workflow (add + commit + push)
82
- gittable quick
83
- gittable q
84
- ```
85
-
86
- ## 📖 Available Commands
87
-
88
- ### Core Commands
89
-
90
- | Command | Aliases | Description |
91
- |---------|---------|-------------|
92
- | `status` | `st`, `s` | Show repository status with color-coded display |
93
- | `info` | | Quick repository overview |
94
- | `add` | | Stage files for commit with interactive selection |
95
- | `commit` | `ci`, `save` | Create commits with conventional format |
96
- | `diff` | | Show changes with formatted output |
97
- | `log` | | View commit history with formatted output |
98
-
99
- ### Workflow Commands ⚡
100
-
101
- | Command | Aliases | Description |
102
- |---------|---------|-------------|
103
- | `quick` | `q` | Full workflow: add + commit + push |
104
- | `add-commit` | `ac` | Stage files and commit in one flow |
105
- | `commit-push` | `cp` | Commit and push in one flow |
106
- | `commit-sync` | `cs` | Commit and sync (fetch + rebase + push) |
107
- | `sync` | | Synchronize (pull + rebase + push) |
108
-
109
- ### Branching Commands
110
-
111
- | Command | Aliases | Description |
112
- |---------|---------|-------------|
113
- | `branch` | `br`, `co` | Branch management (list, create, checkout, delete) |
114
- | `checkout` | `co` | Checkout files or branches |
115
- | `merge` | | Merge branches with interactive prompts |
116
- | `rebase` | | Rebase operations with safety checks |
117
- | `branch-clean` | | Delete merged branches interactively |
118
-
119
- ### Remote Commands
120
-
121
- | Command | Aliases | Description |
122
- |---------|---------|-------------|
123
- | `push` | `ps`, `up` | Push to remote repository |
124
- | `pull` | `pl`, `down` | Fetch and merge from remote |
125
- | `fetch` | | Fetch from remote with status updates |
126
- | `create-pr` | `pr` | Create pull request after push |
127
-
128
- See the [Available Commands](#-available-commands) section above for more commands.
129
-
130
- ## ⚙️ Configuration
131
-
132
- Gittable uses configuration files to customize commit prompts and behavior. Create one of the following files in your project root:
133
-
134
- - `.gittable.js`
135
- - `.gittable.json`
136
- - Or add config to `package.json` under `gittable` key
137
-
138
- ### Example Configuration (`.gittable.js`)
139
-
140
- ```javascript
141
- module.exports = {
142
- types: [
143
- { value: 'feat', name: 'feat: A new feature' },
144
- { value: 'fix', name: 'fix: A bug fix' },
145
- { value: 'docs', name: 'docs: Documentation only changes' },
146
- { value: 'style', name: 'style: Code style changes (formatting, etc.)' },
147
- { value: 'refactor', name: 'refactor: Code refactoring' },
148
- { value: 'perf', name: 'perf: Performance improvements' },
149
- { value: 'test', name: 'test: Adding or updating tests' },
150
- { value: 'chore', name: 'chore: Maintenance tasks' },
151
- ],
152
- scopes: [
153
- 'components',
154
- 'api',
155
- 'auth',
156
- 'db',
157
- 'config',
158
- 'utils',
159
- ],
160
- allowTicketNumber: true,
161
- ticketNumberPrefix: 'TICKET-',
162
- subjectLimit: 100,
163
- allowBreakingChanges: ['feat', 'fix'],
164
- };
165
- ```
166
-
167
- See the [Configuration](#️-configuration) section above for more details.
168
-
169
- ## 📚 Documentation
170
-
171
- - **[Architecture](./ARCHITECTURE.md)** - System architecture and design
172
- - **README** - This file contains installation, usage, and configuration guides
173
-
174
- ## 💡 Usage Examples
175
-
176
- ### Creating a Commit
177
-
178
- ```bash
179
- gittable commit
180
- ```
181
-
182
- This interactive command guides you through:
183
- 1. Selecting commit type (feat, fix, docs, etc.)
184
- 2. Choosing scope (optional)
185
- 3. Entering ticket number (if enabled)
186
- 4. Writing commit message
187
- 5. Adding extended description (optional)
188
- 6. Breaking changes (if applicable)
189
- 7. Issues closed (optional)
190
-
191
- ### Quick Workflow
192
-
193
- ```bash
194
- gittable quick
195
- # or
196
- gittable q
197
- ```
198
-
199
- This will:
200
- 1. Show changes
201
- 2. Stage files (with confirmation)
202
- 3. Create a commit (interactive)
203
- 4. Push to remote (with confirmation)
204
-
205
- ### Combined Commands
206
-
207
- ```bash
208
- # Stage and commit in one flow
209
- gittable add-commit
210
- gittable ac
211
-
212
- # Commit and push
213
- gittable commit-push
214
- gittable cp
215
-
216
- # Commit and sync (fetch + rebase + push)
217
- gittable commit-sync
218
- gittable cs
219
- ```
220
-
221
- ### Branch Management
222
-
223
- ```bash
224
- # List all branches
225
- gittable branch
226
-
227
- # Create and checkout new branch
228
- gittable branch create feature/new-feature
229
-
230
- # Clean up merged branches
231
- gittable branch-clean
232
- ```
233
-
234
- ### Status Check
235
-
236
- ```bash
237
- gittable status
238
- # or use short alias
239
- gittable st
240
- ```
241
-
242
- Shows a beautiful, color-coded status display with:
243
- - Current branch information
244
- - Last commit message and time
245
- - Staged files
246
- - Unstaged files
247
- - Untracked files
248
- - Ahead/behind information relative to remote
249
- - Smart suggestions for next actions
250
-
251
- ## 🛠️ Development
252
-
253
- ### Prerequisites
254
-
255
- - Node.js >= 14.0.0
256
- - npm or yarn
257
- - Git
258
-
259
- ### Setup
260
-
261
- ```bash
262
- # Clone repository
263
- git clone https://github.com/GG-Santos/Gittable.git
264
- cd Gittable
265
-
266
- # Install dependencies
267
- npm install
268
-
269
- # Link for local development
270
- npm link
271
-
272
- # Run tests
273
- npm test
274
-
275
- # Lint code
276
- npm run lint
277
- ```
278
-
279
- For development setup, see the [Development](#️-development) section above.
280
-
281
- ## 🏗️ Architecture
282
-
283
- Gittable uses a modular, category-based architecture for better maintainability and extensibility.
284
-
285
- ### Project Structure
286
-
287
- ```
288
- gittable/
289
- ├── src/
290
- │ ├── cli/ # CLI layer (entry, parsing, routing)
291
- │ ├── commands/ # Commands organized by category
292
- │ ├── core/ # Core business logic
293
- │ ├── ui/ # UI components and framework
294
- │ └── utils/ # Shared utilities
295
- ├── test/ # Test suite (unit, integration, fixtures)
296
- ├── scripts/ # Build and publish scripts
297
- └── index.js # Main entry point
298
- ```
299
-
300
- See [ARCHITECTURE.md](./ARCHITECTURE.md) for detailed architecture documentation.
301
-
302
- ## 📦 Dependencies
303
-
304
- ### Production Dependencies
305
-
306
- - **chalk** (^4.1.2) - Terminal string styling
307
- - **cli-table3** (^0.6.5) - Beautiful tables for CLI output
308
- - **find-config** (^1.0.0) - Configuration file discovery
309
- - **prettycli** (^1.1.0) - Enhanced CLI logging
310
- - **sisteransi** (^1.0.5) - ANSI escape sequences
311
- - **wcwidth** (^1.0.1) - Character width calculation
312
- - **word-wrap** (^1.2.5) - Text wrapping utility
313
-
314
- ### Development Dependencies
315
-
316
- - **@biomejs/biome** (^1.9.4) - Fast formatter and linter
317
-
318
- ## 🤝 Contributing
319
-
320
- Contributions are welcome! Please follow these guidelines:
321
- 1. Fork the repository
322
- 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
323
- 3. Make your changes and add tests
324
- 4. Commit using conventional commits (`feat: add amazing feature`)
325
- 5. Push to your branch (`git push origin feature/amazing-feature`)
326
- 6. Open a Pull Request
327
-
328
- For more details, see the [Development](#️-development) section above.
329
-
330
- ## 📄 License
331
-
332
- This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
333
-
334
- ## 🙏 Acknowledgments
45
+ ## Acknowledgments
335
46
 
336
47
  Gittable is built with the following excellent open-source projects:
337
48
 
@@ -339,21 +50,10 @@ Gittable is built with the following excellent open-source projects:
339
50
  - **[conventional-changelog](https://github.com/conventional-changelog)** - Conventional commits specification
340
51
  - **[chalk](https://github.com/chalk/chalk)** by [@sindresorhus](https://github.com/sindresorhus) - Terminal string styling
341
52
  - **[cli-table3](https://github.com/cli-table/cli-table3)** - Beautiful CLI tables
342
- - **[Biome](https://biomejs.dev/)** - Fast formatter and linter
343
53
 
344
- ## 👤 Author
54
+ ## Author
345
55
 
346
56
  **GG-Santos** from Wab n' Wab Atelier
347
57
 
348
58
  - Email: ggsantos_0415@proton.me
349
- - GitHub: [@GG-Santos](https://github.com/GG-Santos)
350
-
351
- ---
352
-
353
- <div align="center">
354
-
355
- Made with dedication by the Wab n' Wab Atelier
356
-
357
- [Report Bug](https://github.com/GG-Santos/Gittable/issues) • [Request Feature](https://github.com/GG-Santos/Gittable/issues) • [View on GitHub](https://github.com/GG-Santos/Gittable)
358
-
359
- </div>
59
+ - GitHub: [@GG-Santos](https://github.com/GG-Santos)
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.8",
2
+ "version": "1.0.9",
3
3
  "name": "gittable",
4
4
  "description": "Modern Git CLI with Conventional Commits",
5
5
  "main": "index.js",
@@ -12,11 +12,7 @@
12
12
  "lint": "biome check .",
13
13
  "lint:fix": "biome check --write .",
14
14
  "format": "biome format --write .",
15
- "test": "node --test test/**/*.test.js",
16
- "test:watch": "node --test --watch test/**/*.test.js",
17
- "publish:github": "npm publish --registry=https://npm.pkg.github.com",
18
- "publish:npm": "node scripts/publish-npm.js",
19
- "publish:both": "npm run publish:github && npm run publish:npm",
15
+ "package": "npm publish --registry=https://npm.pkg.github.com && node scripts/publish-npm.js",
20
16
  "gittable": "node index.js"
21
17
  },
22
18
  "repository": {
@@ -38,12 +34,19 @@
38
34
  "version-control"
39
35
  ],
40
36
  "dependencies": {
37
+ "@colors/colors": "^1.6.0",
41
38
  "chalk": "^4.1.2",
42
- "cli-table3": "^0.6.5",
39
+ "cli-cursor": "^4.0.0",
40
+ "cli-spinners": "^3.3.0",
43
41
  "find-config": "^1.0.0",
42
+ "is-interactive": "^1.0.0",
43
+ "is-unicode-supported": "^1.3.0",
44
+ "log-symbols": "^5.1.0",
44
45
  "prettycli": "^1.1.0",
45
- "sisteransi": "^1.0.5",
46
- "wcwidth": "^1.0.1",
46
+ "stdin-discarder": "^0.3.0",
47
+ "string-width": "^6.1.0",
48
+ "strip-ansi": "^7.1.2",
49
+ "terminal-link": "^3.0.0",
47
50
  "word-wrap": "^1.2.5"
48
51
  },
49
52
  "devDependencies": {
@@ -73,7 +73,6 @@ function getWorkflowMap() {
73
73
  fileOps: 'File Operations',
74
74
  repoManagement: 'Repository Management',
75
75
  tagging: 'Tagging',
76
- helpLearning: 'Help & Learning',
77
76
  quickActions: 'Quick Actions',
78
77
  undo: 'Undo & Recovery',
79
78
  inspection: 'Inspection',
@@ -82,10 +81,7 @@ function getWorkflowMap() {
82
81
  gittableSettings: {
83
82
  label: 'Gittable Settings',
84
83
  description: 'Configure Gittable appearance and behavior',
85
- subcategories: {
86
- appearance: 'Appearance',
87
- behavior: 'Behavior',
88
- },
84
+ subcategories: null,
89
85
  },
90
86
  };
91
87
  }
@@ -98,12 +94,8 @@ function getWorkflowMap() {
98
94
  function mapCommandToWorkflow(commandName, category, subcategory) {
99
95
  // Special handling for settings commands (utilities category with settings subcategory)
100
96
  if (category === 'utilities' && subcategory === 'settings') {
101
- // Map settings commands to gittableSettings workflow
102
- if (commandName === 'theme') {
103
- return { workflow: 'gittableSettings', subcategory: 'appearance' };
104
- }
105
- // config goes to behavior
106
- return { workflow: 'gittableSettings', subcategory: 'behavior' };
97
+ // Map all settings commands directly to gittableSettings workflow (no subcategory)
98
+ return { workflow: 'gittableSettings', subcategory: null };
107
99
  }
108
100
 
109
101
  // Map workflow category based on subcategory
@@ -140,9 +132,6 @@ function mapCommandToWorkflow(commandName, category, subcategory) {
140
132
  if (subcategory === 'tagging') {
141
133
  return { workflow: 'maintenanceUtilities', subcategory: 'tagging' };
142
134
  }
143
- if (subcategory === 'help' || subcategory === 'commandHistory') {
144
- return { workflow: 'maintenanceUtilities', subcategory: 'helpLearning' };
145
- }
146
135
  if (subcategory === 'inspection') {
147
136
  return { workflow: 'historyInspection', subcategory: 'repositoryState' };
148
137
  }
@@ -150,7 +139,7 @@ function mapCommandToWorkflow(commandName, category, subcategory) {
150
139
  // diff-preview and preview-diff already handled above, but fallback
151
140
  return { workflow: 'dailyDevelopment', subcategory: 'previewChanges' };
152
141
  }
153
- return { workflow: 'maintenanceUtilities', subcategory: 'helpLearning' };
142
+ return { workflow: 'maintenanceUtilities', subcategory: 'quickActions' };
154
143
  }
155
144
 
156
145
  // Map core category
@@ -206,7 +195,7 @@ function mapCommandToWorkflow(commandName, category, subcategory) {
206
195
  }
207
196
 
208
197
  // Default fallback
209
- return { workflow: 'maintenanceUtilities', subcategory: 'helpLearning' };
198
+ return { workflow: 'maintenanceUtilities', subcategory: 'quickActions' };
210
199
  }
211
200
 
212
201
  /**
@@ -244,10 +233,16 @@ function getCommandsByWorkflow(workflow, subcategory = null, config = null) {
244
233
  }
245
234
 
246
235
  // If subcategory is specified, only match commands with that subcategory
236
+ // If subcategory is null, only match commands with null subcategory
247
237
  if (subcategory !== null) {
248
238
  if (mapping.subcategory !== subcategory) {
249
239
  return false;
250
240
  }
241
+ } else {
242
+ // When subcategory is null, only match commands that also have null subcategory
243
+ if (mapping.subcategory !== null) {
244
+ return false;
245
+ }
251
246
  }
252
247
 
253
248
  // Filter by config if provided
@@ -385,7 +380,7 @@ function showHelp() {
385
380
  }
386
381
 
387
382
  const workflowName = workflowInfo.label;
388
- const hasSubcategories = workflowInfo.subcategories !== null;
383
+ const hasSubcategories = workflowInfo.subcategories != null && typeof workflowInfo.subcategories === 'object';
389
384
 
390
385
  if (hasSubcategories) {
391
386
  // Show workflow header
@@ -454,6 +449,45 @@ async function showSubcategoryMenu(workflowKey, workflowInfo) {
454
449
  const config = getConfig();
455
450
  const theme = getTheme();
456
451
 
452
+ // If workflow has no subcategories, show commands directly
453
+ if (!workflowInfo.subcategories) {
454
+ const commands = getCommandsByWorkflow(workflowKey, null, config);
455
+ if (commands.length === 0) {
456
+ prompts.cancel(chalk.yellow('No commands available in this workflow'));
457
+ return showWorkflowMenu();
458
+ }
459
+
460
+ const commandOptions = commands.map((cmd) => {
461
+ const aliases = cmd.aliases.length > 0 ? chalk.dim(` (${cmd.aliases.join(', ')})`) : '';
462
+ return {
463
+ value: cmd.name,
464
+ label: `${theme.primary(cmd.name)}${aliases} ${chalk.gray(`- ${cmd.description}`)}`,
465
+ };
466
+ });
467
+
468
+ commandOptions.push({
469
+ value: INTERACTIVE_MARKERS.BACK,
470
+ label: chalk.dim('← Previous Menu'),
471
+ });
472
+
473
+ const selectedCommand = await prompts.select({
474
+ message: theme.primary(`Select a command from ${workflowInfo.label}:`),
475
+ options: commandOptions,
476
+ });
477
+
478
+ if (prompts.isCancel(selectedCommand) || selectedCommand === INTERACTIVE_MARKERS.BACK) {
479
+ return showWorkflowMenu();
480
+ }
481
+
482
+ // Execute the selected command
483
+ const success = await router.execute(selectedCommand, []);
484
+ if (!success) {
485
+ const { CommandError } = require('../core/errors');
486
+ throw new CommandError(`Command "${selectedCommand}" failed`, selectedCommand);
487
+ }
488
+ return;
489
+ }
490
+
457
491
  const subcategoryOptions = [];
458
492
  const directCommandSubcategories = [];
459
493
  const regularSubcategories = [];
@@ -548,9 +582,13 @@ async function showCommandMenu(workflowKey, subcategory, workflowInfo) {
548
582
  label: chalk.dim('← Previous Menu'),
549
583
  });
550
584
 
585
+ const subcategoryLabel = workflowInfo.subcategories && workflowInfo.subcategories[subcategory]
586
+ ? workflowInfo.subcategories[subcategory]
587
+ : 'this subcategory';
588
+
551
589
  const selectedCommand = await prompts.select({
552
590
  message: theme.primary(
553
- `Select a command from ${workflowInfo.subcategories[subcategory]}:`
591
+ `Select a command from ${subcategoryLabel}:`
554
592
  ),
555
593
  options: commandOptions,
556
594
  });
@@ -595,8 +633,12 @@ async function showWorkflowMenu() {
595
633
 
596
634
  // Count commands in this workflow
597
635
  let commandCount = 0;
598
- for (const subKey of Object.keys(workflowInfo.subcategories)) {
599
- commandCount += getCommandsByWorkflow(workflowKey, subKey, config).length;
636
+ if (workflowInfo.subcategories) {
637
+ for (const subKey of Object.keys(workflowInfo.subcategories)) {
638
+ commandCount += getCommandsByWorkflow(workflowKey, subKey, config).length;
639
+ }
640
+ } else {
641
+ commandCount = getCommandsByWorkflow(workflowKey, null, config).length;
600
642
  }
601
643
 
602
644
  const label =
@@ -606,9 +648,8 @@ async function showWorkflowMenu() {
606
648
  topLevelOptions.push({ value: workflowKey, label });
607
649
  }
608
650
 
609
- // Add help and exit
651
+ // Add exit
610
652
  topLevelOptions.push(
611
- { value: 'help', label: chalk.yellow('List Commands') },
612
653
  { value: 'exit', label: chalk.red('Exit') }
613
654
  );
614
655
 
@@ -618,13 +659,12 @@ async function showWorkflowMenu() {
618
659
  options: topLevelOptions,
619
660
  });
620
661
 
621
- if (prompts.isCancel(selection) || selection === 'exit') {
662
+ if (prompts.isCancel(selection)) {
622
663
  prompts.cancel(chalk.yellow('Cancelled'));
623
664
  return;
624
665
  }
625
666
 
626
- if (selection === 'help') {
627
- showHelp();
667
+ if (selection === 'exit') {
628
668
  return;
629
669
  }
630
670
 
@@ -125,12 +125,13 @@ module.exports = async (args) => {
125
125
  // Execute push with spinner
126
126
  let command = 'push';
127
127
 
128
+ // Add --no-progress to prevent git progress output from interfering with spinner
128
129
  if (pushType === 'tags') {
129
- command += ` ${remote} --tags`;
130
+ command += ` ${remote} --tags --no-progress`;
130
131
  } else if (pushType === 'all') {
131
- command += ` ${remote} --all`;
132
+ command += ` ${remote} --all --no-progress`;
132
133
  } else {
133
- command += ` ${remote} ${branchName}`;
134
+ command += ` ${remote} ${branchName} --no-progress`;
134
135
  if (pushType === 'upstream') {
135
136
  command += ' --set-upstream';
136
137
  } else if (pushType === 'force-with-lease') {
@@ -148,9 +149,30 @@ module.exports = async (args) => {
148
149
 
149
150
  const result = await execGitWithSpinner(command, {
150
151
  spinnerText,
151
- successMessage: 'Push completed',
152
+ silent: true, // Capture output to format it nicely
153
+ successMessage: null, // We'll format it ourselves
152
154
  errorMessage: 'Push failed',
153
- onSuccess: async () => {
155
+ onSuccess: async (result) => {
156
+ // Format and display git output nicely
157
+ // Git push writes output to stderr (not stdout), so check stderr first
158
+ const pushOutput = result.stderr || result.output || '';
159
+
160
+ if (pushOutput.trim()) {
161
+ const outputLines = pushOutput.trim().split('\n');
162
+ outputLines.forEach(line => {
163
+ const trimmed = line.trim();
164
+ // Filter out warnings and empty lines
165
+ if (trimmed &&
166
+ !trimmed.includes('CRLF') &&
167
+ !trimmed.includes('LF') &&
168
+ !trimmed.includes('warning:')) {
169
+ // Format git push output with proper indentation
170
+ console.log(` ${chalk.dim(trimmed)}`);
171
+ }
172
+ });
173
+ }
174
+
175
+ ui.success('Push completed');
154
176
  // Suggest creating PR after successful push
155
177
  if (process.stdin.isTTY && branchName !== 'main' && branchName !== 'master') {
156
178
  const { getPRUrl, detectCIPlatform } = require('../../utils/git');
@@ -111,8 +111,8 @@ const EXAMPLES = {
111
111
  'Tag Management': [
112
112
  { cmd: 'gittable tag', desc: 'List all tags' },
113
113
  { cmd: 'gittable tag create v1.0.0', desc: 'Create a tag' },
114
- { cmd: 'gittable tag-push v1.0.0', desc: 'Create and push tag in one step' },
115
- { cmd: 'gittable tag-delete v1.0.0', desc: 'Delete tag locally and remotely' },
114
+ { cmd: 'gittable tag push v1.0.0', desc: 'Create and push tag in one step' },
115
+ { cmd: 'gittable tag delete v1.0.0', desc: 'Delete tag locally and remotely' },
116
116
  ],
117
117
 
118
118
  'Configuration & Customization': [