From 78aed4e7b811878af807620e5d7fbd7c8b3e8114 Mon Sep 17 00:00:00 2001 From: Thomo1318 Date: Wed, 10 Dec 2025 20:54:54 +1100 Subject: [PATCH 1/3] feat(quality): configure trunk.io and apply formatting --- .github/workflows/ggshield.yml | 22 ++ .pinned | 0 .trunk/.gitignore | 9 + .trunk/configs/.markdownlint.yaml | 2 + .trunk/configs/.shellcheckrc | 7 + .trunk/configs/.yamllint.yaml | 7 + .trunk/trunk.yaml | 37 ++ .windsurfrules | 0 20251210095345527-tree.md | 90 +++++ config-v1.1.0-draft.toml | 89 +++-- config.toml | 184 +++++++--- scripts/gh-helper.sh | 568 +++++++++++++++--------------- templates/security-hooks/pre-push | 66 ++-- 13 files changed, 689 insertions(+), 392 deletions(-) create mode 100644 .github/workflows/ggshield.yml create mode 100644 .pinned create mode 100644 .trunk/.gitignore create mode 100644 .trunk/configs/.markdownlint.yaml create mode 100644 .trunk/configs/.shellcheckrc create mode 100644 .trunk/configs/.yamllint.yaml create mode 100644 .trunk/trunk.yaml create mode 100644 .windsurfrules create mode 100644 20251210095345527-tree.md diff --git a/.github/workflows/ggshield.yml b/.github/workflows/ggshield.yml new file mode 100644 index 0000000..cee0935 --- /dev/null +++ b/.github/workflows/ggshield.yml @@ -0,0 +1,22 @@ +name: GitGuardian Scan + +on: [push, pull_request] + +jobs: + scanning: + name: GitGuardian Scan + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 # fetch all history so multiple commits can be scanned + + - name: GitGuardian scan + uses: GitGuardian/ggshield-action@v1.24.0 + env: + GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }} + GITHUB_PUSH_BASE_SHA: ${{ github.event.base_ref }} + GITHUB_PULL_BASE_SHA: ${{ github.event.pull_request.base.sha }} + GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} diff --git a/.pinned b/.pinned new file mode 100644 index 0000000..e69de29 diff --git a/.trunk/.gitignore b/.trunk/.gitignore new file mode 100644 index 0000000..15966d0 --- /dev/null +++ b/.trunk/.gitignore @@ -0,0 +1,9 @@ +*out +*logs +*actions +*notifications +*tools +plugins +user_trunk.yaml +user.yaml +tmp diff --git a/.trunk/configs/.markdownlint.yaml b/.trunk/configs/.markdownlint.yaml new file mode 100644 index 0000000..b40ee9d --- /dev/null +++ b/.trunk/configs/.markdownlint.yaml @@ -0,0 +1,2 @@ +# Prettier friendly markdownlint config (all formatting rules disabled) +extends: markdownlint/style/prettier diff --git a/.trunk/configs/.shellcheckrc b/.trunk/configs/.shellcheckrc new file mode 100644 index 0000000..8c7b1ad --- /dev/null +++ b/.trunk/configs/.shellcheckrc @@ -0,0 +1,7 @@ +enable=all +source-path=SCRIPTDIR +disable=SC2154 + +# If you're having issues with shellcheck following source, disable the errors via: +# disable=SC1090 +# disable=SC1091 diff --git a/.trunk/configs/.yamllint.yaml b/.trunk/configs/.yamllint.yaml new file mode 100644 index 0000000..184e251 --- /dev/null +++ b/.trunk/configs/.yamllint.yaml @@ -0,0 +1,7 @@ +rules: + quoted-strings: + required: only-when-needed + extra-allowed: ["{|}"] + key-duplicates: {} + octal-values: + forbid-implicit-octal: true diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml new file mode 100644 index 0000000..78141de --- /dev/null +++ b/.trunk/trunk.yaml @@ -0,0 +1,37 @@ +# This file controls the behavior of Trunk: https://docs.trunk.io/cli +# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml +version: 0.1 +cli: + version: 1.25.0 +# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins) +plugins: + sources: + - id: trunk + ref: v1.7.4 + uri: https://github.com/trunk-io/plugins +# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes) +runtimes: + enabled: + - go@1.21.0 + - node@22.16.0 + - python@3.10.8 +# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration) +lint: + enabled: + - yamllint@1.37.1 + - actionlint@1.7.9 + - checkov@3.2.496 + - git-diff-check + - markdownlint@0.47.0 + - prettier@3.7.4 + - shellcheck@0.11.0 + - shfmt@3.6.0 + - taplo@0.10.0 + - trufflehog@3.92.4 +actions: + disabled: + - trunk-announce + - trunk-check-pre-push + - trunk-fmt-pre-commit + enabled: + - trunk-upgrade-available diff --git a/.windsurfrules b/.windsurfrules new file mode 100644 index 0000000..e69de29 diff --git a/20251210095345527-tree.md b/20251210095345527-tree.md new file mode 100644 index 0000000..e4696fd --- /dev/null +++ b/20251210095345527-tree.md @@ -0,0 +1,90 @@ +```markdown +. πŸ“‚ jjConfig +β”œβ”€β”€ πŸ“„ CONTRIBUTING.md +β”œβ”€β”€ πŸ“„ FORCE_PUSH_WARNING.md +β”œβ”€β”€ πŸ“„ IMPLEMENTATION.md +β”œβ”€β”€ πŸ“„ LICENSE +β”œβ”€β”€ πŸ“„ Makefile +β”œβ”€β”€ πŸ“„ PR_DESCRIPTION.md +β”œβ”€β”€ πŸ“„ QUICKSTART.md +β”œβ”€β”€ πŸ“„ README.md +β”œβ”€β”€ πŸ“„ RELEASE_NOTES.md +β”œβ”€β”€ πŸ“„ RELEASE_NOTES_v1.1.1.md +β”œβ”€β”€ πŸ“„ SECURITY_FIX.md +β”œβ”€β”€ πŸ“„ TASKS.md +β”œβ”€β”€ πŸ“„ TROUBLESHOOTING.md +β”œβ”€β”€ πŸ“„ Task4.md +└── πŸ“‚ aliases/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ advanced-workflows.toml +β”‚ β”œβ”€β”€ πŸ“„ community-collection.toml +β”‚ β”œβ”€β”€ πŸ“„ tier2-intermediate.toml +β”‚ β”œβ”€β”€ πŸ“„ tier3-expert.toml +└── πŸ“‚ backups/ +β”‚ β”œβ”€β”€ πŸ“„ VERSION_HISTORY.md +β”‚ └── πŸ“‚ v0.1.0-original/ +β”‚ β”œβ”€β”€ πŸ“„ config.toml +β”‚ β”œβ”€β”€ πŸ“„ metadata.json +β”‚ └── πŸ“‚ v1.0.0-optimized/ +β”‚ β”œβ”€β”€ πŸ“„ config.toml +β”‚ β”œβ”€β”€ πŸ“„ metadata.json +β”‚ └── πŸ“‚ v1.0.2-init-alias/ +β”‚ β”œβ”€β”€ πŸ“„ config.toml +β”‚ β”œβ”€β”€ πŸ“„ metadata.json +β”‚ └── πŸ“‚ v1.1.0-mcp-integration/ +β”‚ β”œβ”€β”€ πŸ“„ config.toml +β”œβ”€β”€ πŸ“„ config-v1-draft.toml +β”œβ”€β”€ πŸ“„ config-v1.1.0-draft.toml +β”œβ”€β”€ πŸ“„ config.toml +β”œβ”€β”€ πŸ“„ config.toml.backup +β”œβ”€β”€ πŸ“„ config.toml.backup-before-repomix +β”œβ”€β”€ πŸ“„ config_update_git_confirm.txt +└── πŸ“‚ git-configs/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ tier2-git-settings.toml +β”‚ β”œβ”€β”€ πŸ“„ tier3-git-advanced.toml +β”œβ”€β”€ πŸ“„ git-settings-analysis.md +β”œβ”€β”€ πŸ“„ relay.config.json +└── πŸ“‚ revsets/ +└── πŸ“‚ revsets-config/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ community-revsets-patterns.toml +β”‚ β”œβ”€β”€ πŸ“„ tier2-revsets-settings.toml +β”‚ β”œβ”€β”€ πŸ“„ tier3-advanced-revsets.toml +β”‚ β”œβ”€β”€ πŸ“„ willhbr-pattern.toml +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ community-patterns.toml +β”‚ β”œβ”€β”€ πŸ“„ tier2-workflow.toml +β”‚ β”œβ”€β”€ πŸ“„ tier3-advanced.toml +└── πŸ“‚ scripts/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ gh-helper.sh +└── πŸ“‚ template-configs/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ community-templates.toml +β”‚ β”œβ”€β”€ πŸ“„ tier2-template-aliases.toml +β”‚ β”œβ”€β”€ πŸ“„ tier3-custom-templates.toml +└── πŸ“‚ templates/ +β”‚ β”œβ”€β”€ πŸ“„ README-mcp-section.md +β”‚ └── πŸ“‚ mcp-hooks/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ post-checkout +β”‚ β”œβ”€β”€ πŸ“„ post-commit +β”‚ β”œβ”€β”€ πŸ“„ post-merge +β”‚ └── πŸ“‚ repomix-hooks/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ post-checkout +β”‚ β”œβ”€β”€ πŸ“„ post-commit +β”‚ β”œβ”€β”€ πŸ“„ post-merge +β”‚ └── πŸ“‚ security-hooks/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ git-confirm-setup.sh +β”‚ β”œβ”€β”€ πŸ“„ pre-commit +β”‚ β”œβ”€β”€ πŸ“„ pre-push +β”œβ”€β”€ πŸ“„ ui-analysis.md +└── πŸ“‚ ui-configs/ +β”‚ β”œβ”€β”€ πŸ“„ README.md +β”‚ β”œβ”€β”€ πŸ“„ synthwave84-colors.toml +β”‚ β”œβ”€β”€ πŸ“„ tier2-ui-settings.toml +β”‚ └── πŸ“„ tier3-advanced-ui.toml +``` diff --git a/config-v1.1.0-draft.toml b/config-v1.1.0-draft.toml index 093696e..fc0100c 100644 --- a/config-v1.1.0-draft.toml +++ b/config-v1.1.0-draft.toml @@ -3,7 +3,7 @@ # ============================================================================ # JJ Configuration - Version 1.1.0-mcp-integration # Created: 2025-11-07 -# +# # Additional configurations available in: # - ~/.config/jj/aliases/ (Command aliases - tier2, tier3, advanced, community) # - ~/.config/jj/revsets/ (Revset aliases - tier2, tier3, community) @@ -46,22 +46,22 @@ git_push_bookmark = '"Thomo1318/push-" ++ change_id.short()' # Template Aliases [template-aliases] -'format_short_id(id)' = 'id.shortest()' -'format_short_change_id(id)' = 'format_short_id(id)' -'format_timestamp(timestamp)' = 'timestamp.ago()' -'format_short_signature(signature)' = 'signature.email().local()' -'format_short_operation_id(id)' = 'id.shortest()' +'format_short_id(id)' = "id.shortest()" +'format_short_change_id(id)' = "format_short_id(id)" +'format_timestamp(timestamp)' = "timestamp.ago()" +'format_short_signature(signature)' = "signature.email().local()" +'format_short_operation_id(id)' = "id.shortest()" 'format_field(key, value)' = 'key ++ ": " ++ value ++ "\n"' # Revset Aliases [revset-aliases] 'mine()' = 'author("steele.thompson13@gmail.com") | committer("steele.thompson13@gmail.com")' 'trunk()' = 'latest(remote_bookmarks(exact:"main") | remote_bookmarks(exact:"master") | remote_bookmarks(exact:"trunk"))' -'work' = 'ancestors(mutable() & ~empty(), 2) | trunk()' -'recent()' = 'ancestors(@, 10)' -'p(n)' = '@-n' -'p(r, n)' = 'r-n' -'active(rev)' = 'ancestors(rev) | descendants(rev) | rev' +'work' = "ancestors(mutable() & ~empty(), 2) | trunk()" +'recent()' = "ancestors(@, 10)" +'p(n)' = "@-n" +'p(r, n)' = "r-n" +'active(rev)' = "ancestors(rev) | descendants(rev) | rev" # Revsets Section [revsets] @@ -77,35 +77,34 @@ ds = ["diff", "--stat"] s = ["show"] c = ["commit"] ci = ["commit", "--interactive"] - # Log viewing l = ["log"] ll = ["log", "--limit", "20"] lll = ["log", "--limit", "50"] - # Editing e = ["edit"] amend = ["squash"] - # Rebase r = ["rebase"] - # Git integration pull = ["git", "fetch"] push = ["git", "push", "--allow-new"] sync = ["git", "fetch", "--all-remotes"] - # New changes n = ["new"] co = ["new"] - # TUI launchers fzf = ["!jj-fzf"] tui = ["!lazyjj"] ui = ["!gg"] - # Repository Initialization (v1.1.0 - MCP-enabled by default) -init = ["util", "exec", "--", "bash", "-c", ''' +init = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e echo "Initializing jj repository with GitMCP integration..." @@ -143,10 +142,16 @@ if [ -n "$REMOTE" ]; then else echo "β„Ή Local repo - MCP context generated for local use" fi -'''] - +''', +] # Short version (same as init) -i = ["util", "exec", "--", "bash", "-c", ''' +i = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e jj git init --colocate mkdir -p .git/hooks @@ -157,13 +162,18 @@ chmod +x .git/hooks/post-* .git/hooks/post-commit REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") [ -n "$REMOTE" ] && echo "GitMCP: https://gitmcp.io/$REMOTE" || echo "Local repo initialized" -'''] - +''', +] # Initialize without MCP (fallback) init-simple = ["git", "init", "--colocate"] - # Install MCP hooks in existing repo -mcp-update = ["util", "exec", "--", "bash", "-c", ''' +mcp-update = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e echo "Installing GitMCP hooks in existing repository..." @@ -180,10 +190,16 @@ chmod +x .git/hooks/post-* echo "βœ“ GitMCP hooks installed" REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") [ -n "$REMOTE" ] && echo "βœ“ GitMCP URL: https://gitmcp.io/$REMOTE" -'''] - +''', +] # Show GitMCP URL for current repo -mcp-url = ["util", "exec", "--", "bash", "-c", ''' +mcp-url = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") if [ -n "$REMOTE" ]; then echo "GitMCP URL: https://gitmcp.io/$REMOTE" @@ -195,17 +211,24 @@ if [ -n "$REMOTE" ]; then else echo "Not a GitHub repository" fi -'''] - +''', +] # Open GitMCP URL in browser -mcp-open = ["util", "exec", "--", "bash", "-c", ''' +mcp-open = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") if [ -n "$REMOTE" ]; then open "https://gitmcp.io/$REMOTE" else echo "Not a GitHub repository" fi -'''] +''', +] # Synthwave84 Color Scheme [colors] diff --git a/config.toml b/config.toml index 7009145..697eefa 100644 --- a/config.toml +++ b/config.toml @@ -3,7 +3,7 @@ # ============================================================================ # JJ Configuration - Version 1.1.0-mcp-integration # Created: 2025-11-07 -# +# # Additional configurations available in: # - ~/.config/jj/aliases/ (Command aliases - tier2, tier3, advanced, community) # - ~/.config/jj/revsets/ (Revset aliases - tier2, tier3, community) @@ -32,11 +32,17 @@ color = "always" # Git Integration [git] -push-new-bookmarks = true -auto-local-bookmark = true +sign-on-push = true +# auto-local-bookmark = true fetch = "glob:*" private-commits = "description(glob:'wip:*') | description(glob:'private:*')" +# Commit Signing (1Password SSH Agent) +[signing] +behavior = "drop" +backend = "ssh" +key = "~/.ssh/id_ed25519.pub" + # Templates [templates] log = "builtin_log_comfortable" @@ -46,22 +52,22 @@ git_push_bookmark = '"Thomo1318/push-" ++ change_id.short()' # Template Aliases [template-aliases] -'format_short_id(id)' = 'id.shortest()' -'format_short_change_id(id)' = 'format_short_id(id)' -'format_timestamp(timestamp)' = 'timestamp.ago()' -'format_short_signature(signature)' = 'signature.email().local()' -'format_short_operation_id(id)' = 'id.shortest()' +'format_short_id(id)' = "id.shortest()" +'format_short_change_id(id)' = "format_short_id(id)" +'format_timestamp(timestamp)' = "timestamp.ago()" +'format_short_signature(signature)' = "signature.email().local()" +'format_short_operation_id(id)' = "id.shortest()" 'format_field(key, value)' = 'key ++ ": " ++ value ++ "\n"' # Revset Aliases [revset-aliases] 'mine()' = 'author("steele.thompson13@gmail.com") | committer("steele.thompson13@gmail.com")' 'trunk()' = 'latest(remote_bookmarks(exact:"main") | remote_bookmarks(exact:"master") | remote_bookmarks(exact:"trunk"))' -'work' = 'ancestors(mutable() & ~empty(), 2) | trunk()' -'recent()' = 'ancestors(@, 10)' -'p(n)' = '@-n' -'p(r, n)' = 'r-n' -'active(rev)' = 'ancestors(rev) | descendants(rev) | rev' +'work' = "ancestors(mutable() & ~empty(), 2) | trunk()" +'recent()' = "ancestors(@, 10)" +'p(n)' = "@-n" +'p(r, n)' = "r-n" +'active(rev)' = "ancestors(rev) | descendants(rev) | rev" # Revsets Section [revsets] @@ -72,10 +78,31 @@ short-prefixes = "(trunk()..@)::" [aliases] # GitHub integration aliases (v1.1.1-gh-integration) # Uses external script for better maintainability and error handling -gh-create = ["util", "exec", "--", "bash", "-c", "~/.config/jj/scripts/gh-helper.sh create"] -init-github = ["util", "exec", "--", "bash", "-c", "~/.config/jj/scripts/gh-helper.sh init-github"] -gh-clone = ["util", "exec", "--", "bash", "-c", "~/.config/jj/scripts/gh-helper.sh clone \"$@\"", "--"] - +gh-create = [ + "util", + "exec", + "--", + "bash", + "-c", + "~/.config/jj/scripts/gh-helper.sh create", +] +init-github = [ + "util", + "exec", + "--", + "bash", + "-c", + "~/.config/jj/scripts/gh-helper.sh init-github", +] +gh-clone = [ + "util", + "exec", + "--", + "bash", + "-c", + "~/.config/jj/scripts/gh-helper.sh clone \"$@\"", + "--", +] # Basic operations st = ["status"] d = ["diff"] @@ -83,41 +110,43 @@ ds = ["diff", "--stat"] s = ["show"] c = ["commit"] ci = ["commit", "--interactive"] - # Log viewing l = ["log"] ll = ["log", "--limit", "20"] lll = ["log", "--limit", "50"] - # Editing e = ["edit"] amend = ["squash"] - # Rebase r = ["rebase"] - # Git integration pull = ["git", "fetch"] push = ["git", "push", "--allow-new"] sync = ["git", "fetch", "--all-remotes"] - # New changes n = ["new"] co = ["new"] - # TUI launchers fzf = ["!jj-fzf"] tui = ["!lazyjj"] ui = ["!gg"] - # Repository Initialization (v1.1.2 - MCP-enabled + git-confirm) -init = ["util", "exec", "--", "bash", "-c", ''' +init = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e echo "Initializing jj repository with GitMCP integration..." # Initialize jj repo jj git init --colocate +# Force usage of local hooks (override global ggshield/other configs) +git config core.hooksPath .git/hooks + # Install GitMCP hooks mkdir -p .git/hooks @@ -167,10 +196,16 @@ if [ -n "$REMOTE" ]; then else echo "β„Ή Local repo - MCP context generated for local use" fi -'''] - +''', +] # Short version (same as init) -i = ["util", "exec", "--", "bash", "-c", ''' +i = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e jj git init --colocate mkdir -p .git/hooks @@ -181,16 +216,24 @@ chmod +x .git/hooks/post-* .git/hooks/post-commit REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") [ -n "$REMOTE" ] && echo "GitMCP: https://gitmcp.io/$REMOTE" || echo "Local repo initialized" -'''] - +''', +] # Initialize without MCP (fallback) init-simple = ["git", "init", "--colocate"] - # Install MCP hooks in existing repo -mcp-update = ["util", "exec", "--", "bash", "-c", ''' +mcp-update = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e echo "Installing GitMCP hooks in existing repository..." +# Force usage of local hooks +git config core.hooksPath .git/hooks + mkdir -p .git/hooks cp ~/.config/jj/templates/mcp-hooks/post-commit .git/hooks/post-commit @@ -212,10 +255,16 @@ chmod +x .git/hooks/pre-push echo "βœ“ GitMCP hooks installed" REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") [ -n "$REMOTE" ] && echo "βœ“ GitMCP URL: https://gitmcp.io/$REMOTE" -'''] - +''', +] # Show GitMCP URL for current repo -mcp-url = ["util", "exec", "--", "bash", "-c", ''' +mcp-url = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") if [ -n "$REMOTE" ]; then echo "GitMCP URL: https://gitmcp.io/$REMOTE" @@ -227,21 +276,33 @@ if [ -n "$REMOTE" ]; then else echo "Not a GitHub repository" fi -'''] - +''', +] # Open GitMCP URL in browser -mcp-open = ["util", "exec", "--", "bash", "-c", ''' +mcp-open = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") if [ -n "$REMOTE" ]; then open "https://gitmcp.io/$REMOTE" else echo "Not a GitHub repository" fi -'''] - +''', +] # Repomix Integration (v1.2.0) # Install/update repomix hooks -repomix-update = ["util", "exec", "--", "bash", "-c", ''' +repomix-update = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e echo "Installing Repomix hooks..." @@ -257,10 +318,16 @@ if command -v repomix &> /dev/null; then else echo "⚠️ repomix not installed. Install with: npm install -g repomix" fi -'''] - +''', +] # Show repomix status -repomix-status = ["util", "exec", "--", "bash", "-c", ''' +repomix-status = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' if [ -f .repomix/context.json ]; then echo "Repomix Status:" cat .repomix/context.json | grep -E "(repository|generated_at|latest_file)" || cat .repomix/context.json @@ -275,8 +342,8 @@ if [ -f .repomix/context.json ]; then else echo "Repomix not initialized. Run: jj repomix-update" fi -'''] - +''', +] # Generate repomix file manually repomix-generate = ["util", "exec", "--", "bash", "-c", ''' if command -v repomix &> /dev/null; then @@ -286,7 +353,6 @@ else echo "⚠️ repomix not installed. Install with: npm install -g repomix" fi '''] - # View latest repomix file repomix-view = ["util", "exec", "--", "bash", "-c", ''' if [ -f .repomix/repomix-latest.txt ]; then @@ -295,7 +361,6 @@ else echo "No repomix file found. Run: jj repomix-generate" fi '''] - # Show token counts repomix-tokens = ["util", "exec", "--", "bash", "-c", ''' if command -v repomix &> /dev/null; then @@ -304,9 +369,6 @@ else echo "⚠️ repomix not installed. Install with: npm install -g repomix" fi '''] - - - # Security Integration (v1.2.0) # Install/update security hooks security-update = ["util", "exec", "--", "bash", "-c", ''' @@ -327,9 +389,14 @@ echo "" echo "To sanitize existing files:" echo " python3 .build-artifacts/sanitize_email.py" '''] - # Check for sensitive information -security-check = ["util", "exec", "--", "bash", "-c", ''' +security-check = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' echo "Checking for sensitive information..." echo "" @@ -348,8 +415,8 @@ else echo "" echo "Run sanitization: python3 .build-artifacts/sanitize_email.py" fi -'''] - +''', +] # Sanitize email addresses security-sanitize = ["util", "exec", "--", "bash", "-c", ''' if [ -f .build-artifacts/sanitize_email.py ]; then @@ -360,7 +427,6 @@ else fi '''] - # Synthwave84 Color Scheme [colors] "commit_id" = { fg = "#24decd", bold = true } @@ -394,3 +460,9 @@ fi "email" = { fg = "#24decd" } "timestamp" = { fg = "#480ca8" } "rest" = { fg = "#f15bb5" } + +[remotes.origin] +auto-track-bookmarks = "glob:*" + +[remotes.upstream] +auto-track-bookmarks = "glob:*" diff --git a/scripts/gh-helper.sh b/scripts/gh-helper.sh index 24ad6ec..887344f 100755 --- a/scripts/gh-helper.sh +++ b/scripts/gh-helper.sh @@ -19,290 +19,296 @@ log_error() { echo -e "${RED}βœ—${NC} $*" >&2; } # Check dependencies check_dependencies() { - local missing=() - - command -v gh >/dev/null 2>&1 || missing+=("gh (GitHub CLI)") - command -v jj >/dev/null 2>&1 || missing+=("jj (Jujutsu)") - command -v git >/dev/null 2>&1 || missing+=("git") - - if [ ${#missing[@]} -gt 0 ]; then - log_error "Missing required dependencies:" - printf '%s\n' "${missing[@]}" | sed 's/^/ - /' - exit 1 - fi - - # Check gh auth status - if ! gh auth status >/dev/null 2>&1; then - log_error "GitHub CLI not authenticated. Run: gh auth login" - exit 1 - fi + local missing=() + + command -v gh >/dev/null 2>&1 || missing+=("gh (GitHub CLI)") + command -v jj >/dev/null 2>&1 || missing+=("jj (Jujutsu)") + command -v git >/dev/null 2>&1 || missing+=("git") + + if [ ${#missing[@]} -gt 0 ]; then + log_error "Missing required dependencies:" + printf '%s\n' "${missing[@]}" | sed 's/^/ - /' + exit 1 + fi + + # Check gh auth status + if ! gh auth status >/dev/null 2>&1; then + log_error "GitHub CLI not authenticated. Run: gh auth login" + exit 1 + fi } # Get GitHub username get_github_username() { - gh api user --jq '.login' 2>/dev/null || echo "" + gh api user --jq '.login' 2>/dev/null || echo "" } # Auto-generate description from repo content auto_generate_description() { - local desc="" - - # Try README.md first line - if [ -f "README.md" ]; then - desc=$(head -1 README.md | sed 's/^# *//' | sed 's/^## *//') - elif [ -f "README" ]; then - desc=$(head -1 README) - elif [ -f "package.json" ]; then - desc=$(jq -r '.description // empty' package.json 2>/dev/null) - elif [ -f "pyproject.toml" ]; then - desc=$(grep '^description = ' pyproject.toml | cut -d'"' -f2 2>/dev/null) - elif [ -f "Cargo.toml" ]; then - desc=$(grep '^description = ' Cargo.toml | cut -d'"' -f2 2>/dev/null) - fi - - # Fallback - [ -z "$desc" ] && desc="Personal repository" - - echo "$desc" + local desc="" + + # Try README.md first line + if [ -f "README.md" ]; then + desc=$(head -1 README.md | sed 's/^# *//' | sed 's/^## *//') + elif [ -f "README" ]; then + desc=$(head -1 README) + elif [ -f "package.json" ]; then + desc=$(jq -r '.description // empty' package.json 2>/dev/null) + elif [ -f "pyproject.toml" ]; then + desc=$(grep '^description = ' pyproject.toml | cut -d'"' -f2 2>/dev/null) + elif [ -f "Cargo.toml" ]; then + desc=$(grep '^description = ' Cargo.toml | cut -d'"' -f2 2>/dev/null) + fi + + # Fallback + [ -z "$desc" ] && desc="Personal repository" + + echo "$desc" } # Prompt for input with default prompt_with_default() { - local prompt="$1" - local default="$2" - local value - - if [ -n "$default" ]; then - read -rp "$(echo -e "${prompt} ${YELLOW}[${default}]${NC}: ")" value - echo "${value:-$default}" - else - read -rp "${prompt}: " value - echo "$value" - fi + local prompt="$1" + local default="$2" + local value + + if [ -n "$default" ]; then + read -rp "$(echo -e "${prompt} ${YELLOW}[${default}]${NC}: ")" value + echo "${value:-$default}" + else + read -rp "${prompt}: " value + echo "$value" + fi } # Prompt for yes/no prompt_yes_no() { - local prompt="$1" - local default="${2:-n}" - local value - - if [ "$default" = "y" ]; then - read -rp "$(echo -e "${prompt} ${YELLOW}[Y/n]${NC}: ")" value - value="${value:-y}" - else - read -rp "$(echo -e "${prompt} ${YELLOW}[y/N]${NC}: ")" value - value="${value:-n}" - fi - - [[ "$value" =~ ^[Yy] ]] + local prompt="$1" + local default="${2:-n}" + local value + + if [ "$default" = "y" ]; then + read -rp "$(echo -e "${prompt} ${YELLOW}[Y/n]${NC}: ")" value + value="${value:-y}" + else + read -rp "$(echo -e "${prompt} ${YELLOW}[y/N]${NC}: ")" value + value="${value:-n}" + fi + + [[ $value =~ ^[Yy] ]] } # Create GitHub repository cmd_create() { - log_info "Creating GitHub repository..." - check_dependencies - - local username - username=$(get_github_username) - [ -z "$username" ] && { log_error "Could not determine GitHub username"; exit 1; } - - # Get repository name - local repo_name - local default_name - default_name=$(basename "$PWD") - repo_name=$(prompt_with_default "Repository name" "$default_name") - - # Validate repo name - if [[ ! "$repo_name" =~ ^[a-zA-Z0-9._-]+$ ]]; then - log_error "Invalid repository name. Use only letters, numbers, dots, hyphens, and underscores." - exit 1 - fi - - # Get description - local description - local auto_desc - auto_desc=$(auto_generate_description) - description=$(prompt_with_default "Description" "$auto_desc") - - # Choose visibility - echo "" - log_info "Repository visibility:" - echo " 1) Public" - echo " 2) Private" - local visibility - read -rp "Choose (1 or 2) [1]: " visibility - visibility="${visibility:-1}" - - local visibility_flag="--public" - [ "$visibility" = "2" ] && visibility_flag="--private" - - # Confirm - echo "" - log_info "Summary:" - echo " Repository: ${username}/${repo_name}" - echo " Description: ${description}" - echo " Visibility: $([ "$visibility" = "2" ] && echo "Private" || echo "Public")" - echo "" - - if ! prompt_yes_no "Create repository?" "y"; then - log_warning "Cancelled" - exit 0 - fi - - # Create repository - if gh repo create "${username}/${repo_name}" $visibility_flag \ - --description "$description" 2>/dev/null; then - log_success "Repository created: https://github.com/${username}/${repo_name}" - else - log_error "Failed to create repository" - exit 1 - fi + log_info "Creating GitHub repository..." + check_dependencies + + local username + username=$(get_github_username) + [ -z "$username" ] && { + log_error "Could not determine GitHub username" + exit 1 + } + + # Get repository name + local repo_name + local default_name + default_name=$(basename "$PWD") + repo_name=$(prompt_with_default "Repository name" "$default_name") + + # Validate repo name + if [[ ! $repo_name =~ ^[a-zA-Z0-9._-]+$ ]]; then + log_error "Invalid repository name. Use only letters, numbers, dots, hyphens, and underscores." + exit 1 + fi + + # Get description + local description + local auto_desc + auto_desc=$(auto_generate_description) + description=$(prompt_with_default "Description" "$auto_desc") + + # Choose visibility + echo "" + log_info "Repository visibility:" + echo " 1) Public" + echo " 2) Private" + local visibility + read -rp "Choose (1 or 2) [1]: " visibility + visibility="${visibility:-1}" + + local visibility_flag="--public" + [ "$visibility" = "2" ] && visibility_flag="--private" + + # Confirm + echo "" + log_info "Summary:" + echo " Repository: ${username}/${repo_name}" + echo " Description: ${description}" + echo " Visibility: $([ "$visibility" = "2" ] && echo "Private" || echo "Public")" + echo "" + + if ! prompt_yes_no "Create repository?" "y"; then + log_warning "Cancelled" + exit 0 + fi + + # Create repository + if gh repo create "${username}/${repo_name}" $visibility_flag \ + --description "$description" 2>/dev/null; then + log_success "Repository created: https://github.com/${username}/${repo_name}" + else + log_error "Failed to create repository" + exit 1 + fi } # Initialize jj repo and push to GitHub cmd_init_github() { - log_info "Initializing jj repository and creating GitHub repo..." - check_dependencies - - # Check if already in a jj repo - if [ -d ".jj" ]; then - log_error "Already in a jj repository" - exit 1 - fi - - local username - username=$(get_github_username) - [ -z "$username" ] && { log_error "Could not determine GitHub username"; exit 1; } - - # Get repository name - local repo_name - local default_name - default_name=$(basename "$PWD") - repo_name=$(prompt_with_default "Repository name" "$default_name") - - # Validate repo name - if [[ ! "$repo_name" =~ ^[a-zA-Z0-9._-]+$ ]]; then - log_error "Invalid repository name" - exit 1 - fi - - # Get description - local description - local auto_desc - auto_desc=$(auto_generate_description) - description=$(prompt_with_default "Description" "$auto_desc") - - # Choose visibility - echo "" - log_info "Repository visibility:" - echo " 1) Public" - echo " 2) Private" - local visibility - read -rp "Choose (1 or 2) [1]: " visibility - visibility="${visibility:-1}" - - local visibility_flag="--public" - [ "$visibility" = "2" ] && visibility_flag="--private" - - # Confirm - echo "" - log_info "Summary:" - echo " Repository: ${username}/${repo_name}" - echo " Description: ${description}" - echo " Visibility: $([ "$visibility" = "2" ] && echo "Private" || echo "Public")" - echo "" - - if ! prompt_yes_no "Create repository and initialize?" "y"; then - log_warning "Cancelled" - exit 0 - fi - - # Create GitHub repository - log_info "Creating GitHub repository..." - if ! gh repo create "${username}/${repo_name}" $visibility_flag \ - --description "$description" 2>/dev/null; then - log_error "Failed to create repository" - exit 1 - fi - log_success "Repository created" - - # Initialize jj - log_info "Initializing jj repository..." - if ! jj init --git 2>/dev/null; then - log_error "Failed to initialize jj repository" - exit 1 - fi - log_success "jj initialized" - - # Add remote - log_info "Adding remote..." - if ! git remote add origin "https://github.com/${username}/${repo_name}.git" 2>/dev/null; then - log_warning "Remote might already exist" - fi - - # Create main bookmark - log_info "Creating main bookmark..." - if ! jj bookmark create main -r @- 2>/dev/null; then - log_warning "Bookmark might already exist" - fi - - # Push - log_info "Pushing to GitHub..." - if jj git push --bookmark main --allow-new 2>/dev/null; then - log_success "Pushed to GitHub" - echo "" - log_success "Complete! https://github.com/${username}/${repo_name}" - else - log_error "Failed to push to GitHub" - exit 1 - fi + log_info "Initializing jj repository and creating GitHub repo..." + check_dependencies + + # Check if already in a jj repo + if [ -d ".jj" ]; then + log_error "Already in a jj repository" + exit 1 + fi + + local username + username=$(get_github_username) + [ -z "$username" ] && { + log_error "Could not determine GitHub username" + exit 1 + } + + # Get repository name + local repo_name + local default_name + default_name=$(basename "$PWD") + repo_name=$(prompt_with_default "Repository name" "$default_name") + + # Validate repo name + if [[ ! $repo_name =~ ^[a-zA-Z0-9._-]+$ ]]; then + log_error "Invalid repository name" + exit 1 + fi + + # Get description + local description + local auto_desc + auto_desc=$(auto_generate_description) + description=$(prompt_with_default "Description" "$auto_desc") + + # Choose visibility + echo "" + log_info "Repository visibility:" + echo " 1) Public" + echo " 2) Private" + local visibility + read -rp "Choose (1 or 2) [1]: " visibility + visibility="${visibility:-1}" + + local visibility_flag="--public" + [ "$visibility" = "2" ] && visibility_flag="--private" + + # Confirm + echo "" + log_info "Summary:" + echo " Repository: ${username}/${repo_name}" + echo " Description: ${description}" + echo " Visibility: $([ "$visibility" = "2" ] && echo "Private" || echo "Public")" + echo "" + + if ! prompt_yes_no "Create repository and initialize?" "y"; then + log_warning "Cancelled" + exit 0 + fi + + # Create GitHub repository + log_info "Creating GitHub repository..." + if ! gh repo create "${username}/${repo_name}" $visibility_flag \ + --description "$description" 2>/dev/null; then + log_error "Failed to create repository" + exit 1 + fi + log_success "Repository created" + + # Initialize jj + log_info "Initializing jj repository..." + if ! jj git init --colocate 2>/dev/null; then + log_error "Failed to initialize jj repository" + exit 1 + fi + log_success "jj initialized" + + # Add remote (SSH for 1Password agent compatibility) + log_info "Adding remote..." + if ! git remote add origin "git@github.com:${username}/${repo_name}.git" 2>/dev/null; then + log_warning "Remote might already exist" + fi + + # Create main bookmark + log_info "Creating main bookmark..." + if ! jj bookmark create main -r @- 2>/dev/null; then + log_warning "Bookmark might already exist" + fi + + # Push + log_info "Pushing to GitHub..." + if jj git push --bookmark main --allow-new 2>/dev/null; then + log_success "Pushed to GitHub" + echo "" + log_success "Complete! https://github.com/${username}/${repo_name}" + else + log_error "Failed to push to GitHub" + exit 1 + fi } # Clone GitHub repo and init with jj cmd_clone() { - log_info "Cloning GitHub repository..." - check_dependencies - - local repo_url="$1" - - if [ -z "$repo_url" ]; then - read -rp "Repository URL or owner/repo: " repo_url - fi - - # Validate input - if [ -z "$repo_url" ]; then - log_error "Repository URL required" - exit 1 - fi - - # Clone with gh - log_info "Cloning repository..." - if ! gh repo clone "$repo_url" 2>/dev/null; then - log_error "Failed to clone repository" - exit 1 - fi - - # Extract repo name - local repo_name - repo_name=$(basename "$repo_url" .git) - - # Initialize jj - log_info "Initializing jj in ${repo_name}..." - cd "$repo_name" || exit 1 - - if jj init --git-repo=. 2>/dev/null; then - log_success "jj initialized" - log_success "Complete! Repository ready at: ${PWD}" - else - log_error "Failed to initialize jj" - exit 1 - fi + log_info "Cloning GitHub repository..." + check_dependencies + + local repo_url="$1" + + if [ -z "$repo_url" ]; then + read -rp "Repository URL or owner/repo: " repo_url + fi + + # Validate input + if [ -z "$repo_url" ]; then + log_error "Repository URL required" + exit 1 + fi + + # Clone with gh + log_info "Cloning repository..." + if ! gh repo clone "$repo_url" 2>/dev/null; then + log_error "Failed to clone repository" + exit 1 + fi + + # Extract repo name + local repo_name + repo_name=$(basename "$repo_url" .git) + + # Initialize jj + log_info "Initializing jj in ${repo_name}..." + cd "$repo_name" || exit 1 + + if jj init --git-repo=. 2>/dev/null; then + log_success "jj initialized" + log_success "Complete! Repository ready at: ${PWD}" + else + log_error "Failed to initialize jj" + exit 1 + fi } # Show usage usage() { - cat </dev/null 2>&1; then + echo "⚠️ ggshield not found in PATH" + echo " Skipping secret scan (install with 'brew install ggshield')" + exit 0 +fi -# Check if sanitization script exists -if [ ! -f .build-artifacts/sanitize_all.py ]; then - echo "⚠️ Sanitization script not found" - echo " Expected: .build-artifacts/sanitize_all.py" - exit 0 +# Check if user is authenticated (fast check) +if ! ggshield quota >/dev/null 2>&1; then + echo "⚠️ ggshield not authenticated" + echo " Run 'ggshield auth login' to enable secret scanning" + exit 0 fi -# Run comprehensive sanitization (includes repomix files) -python3 .build-artifacts/sanitize_all.py +echo "πŸ›‘οΈ Scanning for secrets (GitGuardian)..." + +# Scan commits being pushed +# $1 = remote name, $2 = remote URL +# Input format: +while read local_ref local_sha remote_ref remote_sha; do + echo "πŸ” Scanning push: $local_ref ($local_sha) -> $remote_ref ($remote_sha)" + + if [ "$local_sha" = "0000000000000000000000000000000000000000" ]; then + echo "ℹ️ Deletion detected, skipping scan." + continue + fi -# Stage all sanitized files -git add -u + if [ "$remote_sha" = "0000000000000000000000000000000000000000" ]; then + # New branch - scan all commits (fallback to HEAD^1 for safety if just one commit) + echo "πŸ†• New branch detected. Scanning HEAD." + # Use HEAD~1 if it exists, otherwise just HEAD + if git rev-parse HEAD~1 >/dev/null 2>&1; then + RANGE="HEAD~1..HEAD" + else + RANGE="HEAD" + fi -echo "" -echo "βœ… All files sanitized (including .repomix/)" -echo " Real email β†’ Placeholder for public repo" -echo "" -echo "⚠️ Note: After push, restore locally with:" -echo " sed -i '' 's/YOUR_EMAIL@example.com/steele.thompson13@gmail.com/g' config.toml README.md QUICKSTART.md TASKS.md" + # In pre-push, for a new branch, we might want to scan all commits unique to this branch + # But for new repo, HEAD works. + ggshield secret scan commit-range "$RANGE" || exit 1 + else + # Scan range + echo "πŸ”„ Scanning commit range: $remote_sha..$local_sha" + ggshield secret scan commit-range "$remote_sha..$local_sha" || exit 1 + fi +done exit 0 From 8fe753fbeec6ba438075af54575e3d5a68d923de Mon Sep 17 00:00:00 2001 From: Thomo1318 Date: Tue, 30 Dec 2025 23:24:43 +1100 Subject: [PATCH 2/3] feat(tools): add ai-review script using coderabbit cli --- scripts/ai-review.sh | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100755 scripts/ai-review.sh diff --git a/scripts/ai-review.sh b/scripts/ai-review.sh new file mode 100755 index 0000000..73dc131 --- /dev/null +++ b/scripts/ai-review.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# scripts/ai-review.sh +# 🐰 Wrapper for CodeRabbit CLI (Gemini Integration) +# Usage: ./scripts/ai-review.sh [uncommitted|committed|all] + +TYPE="${1:-uncommitted}" + +# 1. Check if CodeRabbit is installed +if ! command -v coderabbit &> /dev/null; then + echo "❌ Error: 'coderabbit' CLI not found." + echo "Please install it: curl -fsSL https://cli.coderabbit.ai/install.sh | sh" + exit 1 +fi + +echo "🐰 Rabbit Check: Analyzing $TYPE changes..." +echo "----------------------------------------" + +# 2. Run CodeRabbit in Machine-Readable mode (--prompt-only) +# We capture stderr to check for "No files found" which is not a real error for us. +OUTPUT=$(coderabbit review --prompt-only -t "$TYPE" 2>&1) +EXIT_CODE=$? + +# 3. Handle Output +if [[ $EXIT_CODE -ne 0 ]]; then + if echo "$OUTPUT" | grep -q "No files found"; then + echo "βœ… Clean State: No changes found to review." + exit 0 + else + echo "❌ Review Failed:" + echo "$OUTPUT" + exit $EXIT_CODE + fi +fi + +# 4. Success - Print the AI Analysis +echo "$OUTPUT" +echo "----------------------------------------" +echo "βœ… Analysis Complete." From 857a116d4f4868304872ec7c2afbf3fdc75c97d3 Mon Sep 17 00:00:00 2001 From: Thomo1318 Date: Wed, 31 Dec 2025 00:32:00 +1100 Subject: [PATCH 3/3] feat: validate and fix publication workflow artifacts --- .agent/workflows/publish-change.md | 52 +++++++++++ .github/workflows/ggshield.yml | 9 +- .gitignore | 1 + .mcp/README.md | 6 +- .mcp/context.json | 4 +- .relay/prompts/system-prompt.md | 100 --------------------- CONTRIBUTING.md | 45 ++++++++-- QUICKSTART.md | 3 +- README.md | 73 ++++++++------- TASKS.md | 95 +++++++++++++++----- backups/VERSION_HISTORY.md | 37 +++++++- backups/v1.1.0-mcp-integration/config.toml | 55 +++++++++--- config-v1.1.0-draft.toml | 38 ++++++-- scripts/ai-review.sh | 14 +-- templates/security-hooks/pre-commit | 27 +++--- 15 files changed, 353 insertions(+), 206 deletions(-) create mode 100644 .agent/workflows/publish-change.md delete mode 100644 .relay/prompts/system-prompt.md diff --git a/.agent/workflows/publish-change.md b/.agent/workflows/publish-change.md new file mode 100644 index 0000000..650b3e6 --- /dev/null +++ b/.agent/workflows/publish-change.md @@ -0,0 +1,52 @@ +--- +description: Pipeline to test, sanitize, and publish changes to jjConfig +--- + +### 1. Quality Assurance + +Verify that the code meets quality standards and documentation is up to date. + +0. Update Documentation Checklist: + - [ ] `TASKS.md`: Mark completed items, add next steps + - [ ] `backups/VERSION_HISTORY.md`: Add version/change notes + - [ ] `README.md`: Update feature list if user-facing changes + +1. Check for linting and formatting errors + `trunk check` + +2. (Optional) Run AI review for final check + `scripts/ai-review.sh` + +### 2. Security & Sanitization + +**CRITICAL**: Remove all personal identifiable information (PII) before snapshotting. + +// turbo 3. Run the robust sanitization script (includes auto-discovery) +`jj security-sanitize` + +### 3. Commit & Publish + +Finalize the snapshot and push to the remote. + +4. Describe the changes (Write a good commit message) + `jj describe` + +5. Push to GitHub (Triggers GitGuardian pre-push hook) + `jj git push` + +6. Create the Pull Request + `gh pr create --web` + +### 4. Restore Local State + +**Important**: Restore your local configuration (email) so you can continue working. + +7. Restore PII (Email) + `python3 .build-artifacts/sanitize_email.py --restore` + +### 5. Release (After Merge) + +Once the PR is approved and merged into the integration branch: + +7. Create a release tag + `gh release create v1.0.0 --generate-notes` diff --git a/.github/workflows/ggshield.yml b/.github/workflows/ggshield.yml index cee0935..b98f4e3 100644 --- a/.github/workflows/ggshield.yml +++ b/.github/workflows/ggshield.yml @@ -2,21 +2,24 @@ name: GitGuardian Scan on: [push, pull_request] +permissions: + contents: read + jobs: scanning: name: GitGuardian Scan runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 # fetch all history so multiple commits can be scanned - name: GitGuardian scan - uses: GitGuardian/ggshield-action@v1.24.0 + uses: GitGuardian/ggshield-action@v1 env: GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }} - GITHUB_PUSH_BASE_SHA: ${{ github.event.base_ref }} + GITHUB_PUSH_BASE_SHA: ${{ github.event.before }} GITHUB_PULL_BASE_SHA: ${{ github.event.pull_request.base.sha }} GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }} diff --git a/.gitignore b/.gitignore index 5aaf89e..bccaed9 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,4 @@ backups/v*/applied-*.timestamp # relay state /.relay/ +.cache_ggshield diff --git a/.mcp/README.md b/.mcp/README.md index 25dc56b..7080afe 100644 --- a/.mcp/README.md +++ b/.mcp/README.md @@ -3,7 +3,7 @@ **Repository:** jjConfig **GitHub:** Thomo1318/jjConfig **MCP Server:** https://gitmcp.io/Thomo1318/jjConfig -**Updated:** 2025-12-05T10:03:59Z +**Updated:** 2026-01-01T06:52:31Z ## Quick Setup @@ -25,5 +25,5 @@ Context files update automatically via Git hooks. ## Status - Branch: -- Commit: 1a85507dda70e8d1a1748939d0853e8745442284 -- Generated: 2025-12-05T10:03:59Z +- Commit: b816691632b5db370256130f3bd670a6f17a9d64 +- Generated: 2026-01-01T06:52:31Z diff --git a/.mcp/context.json b/.mcp/context.json index 4eed82e..bcf4158 100644 --- a/.mcp/context.json +++ b/.mcp/context.json @@ -4,9 +4,9 @@ "github_url": "https://github.com/Thomo1318/jjConfig.git", "mcp_url": "https://gitmcp.io/Thomo1318/jjConfig", "is_github_repo": true, - "generated_at": "2025-12-05T10:03:59Z", + "generated_at": "2026-01-01T06:52:31Z", "branch": "", - "commit": "1a85507dda70e8d1a1748939d0853e8745442284", + "commit": "b816691632b5db370256130f3bd670a6f17a9d64", "mcp_endpoints": { "readme": "https://gitmcp.io/Thomo1318/jjConfig/readme", "docs": "https://gitmcp.io/Thomo1318/jjConfig/docs", diff --git a/.relay/prompts/system-prompt.md b/.relay/prompts/system-prompt.md deleted file mode 100644 index 04c2d5e..0000000 --- a/.relay/prompts/system-prompt.md +++ /dev/null @@ -1,100 +0,0 @@ -You are an expert AI programmer. To modify a file, you MUST use a code block with a specified patch strategy. - -**Syntax:** -```typescript // filePath {patchStrategy} -... content ... -``` -- `filePath`: The path to the file. **If the path contains spaces, it MUST be enclosed in double quotes.** -- `patchStrategy`: (Optional) One of `standard-diff`, `search-replace`. If omitted, the entire file is replaced (this is the `replace` strategy). - -**Examples:** -```typescript // src/components/Button.tsx -... -``` -```typescript // "src/components/My Component.tsx" standard-diff -... -``` ---- - -### Strategy 1: Advanced Unified Diff (`standard-diff`) - RECOMMENDED - -Use for most changes, like refactoring, adding features, and fixing bugs. It's resilient to minor changes in the source file. - -**Diff Format:** -1. **File Headers**: Start with `--- {filePath}` and `+++ {filePath}`. -2. **Hunk Header**: Use `@@ ... @@`. Exact line numbers are not needed. -3. **Context Lines**: Include 2-3 unchanged lines before and after your change for context. -4. **Changes**: Mark additions with `+` and removals with `-`. Maintain indentation. - -**Example:** -```diff ---- src/utils.ts -+++ src/utils.ts -@@ ... @@ - function calculateTotal(items: number[]): number { -- return items.reduce((sum, item) => { -- return sum + item; -- }, 0); -+ const total = items.reduce((sum, item) => { -+ return sum + item * 1.1; // Add 10% markup -+ }, 0); -+ return Math.round(total * 100) / 100; // Round to 2 decimal places -+ } -``` - ---- - -### Strategy 2: Search-Replace (`search-replace`) - -Use for precise, surgical replacements. The `SEARCH` block must be an exact match of the content in the file. - -**Diff Format:** -Repeat this block for each replacement. -```diff -<<<<<<< SEARCH -[exact content to find including whitespace] -======= -[new content to replace with] ->>>>>>> REPLACE -``` - ---- - -### Other Operations - -- **Creating a file**: Use the default `replace` strategy (omit the strategy name) and provide the full file content. -- **Deleting a file**: - ```typescript // path/to/file.ts - //TODO: delete this file - ``` - ```typescript // "path/to/My Old Component.ts" - //TODO: delete this file - ``` -- **Renaming/Moving a file**: - ```json // rename-file - { - "from": "src/old/path/to/file.ts", - "to": "src/new/path/to/file.ts" - } - ``` - ---- - -### Final Steps - -1. Add your step-by-step reasoning in plain text before each code block. -2. ALWAYS add the following YAML block at the very end of your response. Use the exact projectId shown here. Generate a new random uuid for each response. - - ```yaml - projectId: jjConfig - uuid: (generate a random uuid) - changeSummary: # A list of key-value pairs for changes - - edit: src/main.ts - - new: src/components/Button.tsx - - delete: src/utils/old-helper.ts - promptSummary: A brief summary of my request. - gitCommitMsg: >- - feat: A concise, imperative git commit message. - - Optionally, provide a longer description here. - ``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c05fb87..7a9d17b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,13 +33,41 @@ make test # Deploy to test make deploy -β€©βœοΈ Making Changes -Configuration Changes - 1. Edit the main config: ⁠config.toml
 2. Add reference files: Place in appropriate subdirectory (⁠aliases/, ⁠revsets/, etc.)
 3. Update documentation: Reflect changes in relevant README files -Documentation Changes - 1. Follow markdown best practices
 2. Use proper headings (H1-H6)
 3. Include code examples with syntax highlighting
 4. Add emojis for visual appeal (sparingly)
 5. Test all links -Adding New Features - 1. Create reference file in appropriate directory
 2. Add to README in that directory
 3. Update main README if user-facing
 4. Add to TASKS.md if part of roadmap +
## ✏️ Making Changes + +### The Golden Workflow + +Follow this "Inner Loop" to ensure quality and security: + +#### 1. The Inner Loop (Iterate) +> **Goal**: Get the code working and documented locally. +1. **Code**: `micro config.toml` (Edit your files) +2. **Test**: `make test` or `trunk check` (Verify immediately) +3. **Docs**: Update `README.md` or `alias/*.md` **in parallel** with code changes. +4. *Repeat until tests pass and docs match code.* + +#### 2. Quality Assurance +> **Goal**: Polish before committing. +1. **Formating**: `trunk fmt` (Standardize style) +2. **AI Review**: `scripts/ai-review.sh` (Catch bugs/impovements) + +#### 3. Commit & Sanitize +> **Goal**: Secure your work. +1. **Snapshot**: `jj describe -m "feat: description"` +2. **Sanitize**: `jj security-sanitize` (Scrub PII/emails) + * *Critical*: Must run before pushing! + +#### 4. Publish +> **Goal**: Share with the world. +1. **Push**: `jj git push` + * *Note*: This triggers the `pre-push` hook (GitGuardian). +2. **PR**: `gh pr create` (Triggers CI/CD) + +### Adding New Features +1. Create reference file in appropriate directory +2. Add to README in that directory +3. Update main README if user-facing +4. Add to TASKS.md if part of roadmap πŸ§ͺ Testing Changes Syntax Validation 
# Test configuration syntax @@ -178,4 +206,5 @@ We welcome feature requests! Please include: Your contributions make jjConfig better for everyone. We appreciate your time and effort! Happy contributing! πŸŽ‰ 
 ---- \ No newline at end of file +--- +``` diff --git a/QUICKSTART.md b/QUICKSTART.md index 37f42d1..7c8a4b0 100644 --- a/QUICKSTART.md +++ b/QUICKSTART.md @@ -116,4 +116,5 @@ Need Help? β€’ Troubleshooting: TROUBLESHOOTING.md
 β€’ Contributing: CONTRIBUTING.md
 β€’ Issues: https://github.com/Thomo1318/jjConfig/issues
 β€’ jj Discord: https://discord.gg/dkmfj3aGQN Happy hacking! πŸŽ‰ 
 ---- \ No newline at end of file +--- +``` diff --git a/README.md b/README.md index dc38793..a51b786 100644 --- a/README.md +++ b/README.md @@ -44,18 +44,19 @@ ## πŸ”§ Prerequisites -| Requirement | Version | Installation | -| -------------- | --------- | ------------------------------------------------------------ | -| **Jujutsu (jj)** | 0.23.0+ | `brew install jj` or [build from source](https://github.com/jj-vcs/jj) | -| **Git** | 2.40+ | `brew install git` | -| **Bash** | 4.0+ | Pre-installed on macOS/Linux | -| **Make** | 3.81+ | Pre-installed on macOS/Linux | - -**Optional:** -- [jj-fzf](https://github.com/Cretezy/jj-fzf) -- [lazyjj](https://github.com/Cretezy/lazyjj) -- [gg](https://github.com/gulbanana/gg) -- [micro editor](https://micro-editor.github.io/) +| Requirement | Version | Installation | +| ---------------- | ------- | ---------------------------------------------------------------------- | +| **Jujutsu (jj)** | 0.23.0+ | `brew install jj` or [build from source](https://github.com/jj-vcs/jj) | +| **Git** | 2.40+ | `brew install git` | +| **Bash** | 4.0+ | Pre-installed on macOS/Linux | +| **Make** | 3.81+ | Pre-installed on macOS/Linux | + +**Optional:** + +- [jj-fzf](https://github.com/Cretezy/jj-fzf) +- [lazyjj](https://github.com/Cretezy/lazyjj) +- [gg](https://github.com/gulbanana/gg) +- [micro editor](https://micro-editor.github.io/) --- @@ -109,6 +110,7 @@ jj fzf # jj-fzf jj tui # lazyjj jj ui # gg ``` + More aliases, advanced workflows, and troubleshooting: see [`aliases/README.md`](aliases/README.md). --- @@ -140,6 +142,7 @@ jj push Main config: `config.toml` (v1.1.0-mcp-integration) Sections include: + - `[user]` name and email - `[ui]` editor, pager, colors - `[git]` integration settings @@ -147,6 +150,7 @@ Sections include: - `[revset-aliases]` custom commit queries Reference documentation: + - [`aliases/README.md`](aliases/README.md) for command aliases and workflow scripts - [`revsets/README.md`](revsets/README.md) for revset language and practical queries - [`ui-configs/README.md`](ui-configs/README.md) for UI, color, and diff/pager settings @@ -162,16 +166,19 @@ Above files have verified relevant documentation for usage and implementation. GitMCP provides local AI repository context for toolsβ€”no API tokens required. -**How It Works:** -- Git hooks (`post-commit`, `post-merge`, `post-checkout`) generate `.mcp/context.json` -- 100% local processing +**How It Works:** + +- Git hooks (`post-commit`, `post-merge`, `post-checkout`) generate `.mcp/context.json` +- 100% local processing - Compatible with IDEs and desktop AIs -**Setup:** +**Setup:** + ```bash cat .mcp/cursor-config.json >> ~/.cursor/mcp.json # Cursor IDE cat .mcp/claude-config.json >> ~/Library/Application\ Support/Claude/claude_desktop_config.json # Claude Desktop ``` + MCP server URL: `https://gitmcp.io/Thomo1318/jjConfig` @@ -183,13 +190,15 @@ See [MCP docs](https://gitmcp.io/docs) for details. Repomix consolidates your entire repository into a single AI-friendly file for context injection. -**How It Works:** -- Git hooks automatically generate `.repomix/repomix-latest.txt` after commits -- Contains full repository content optimized for AI tools -- Includes token counts and file statistics +**How It Works:** + +- Git hooks automatically generate `.repomix/repomix-latest.txt` after commits +- Contains full repository content optimized for AI tools +- Includes token counts and file statistics - Automatic cleanup (keeps last 3 versions) -**Generated Files:** +**Generated Files:** + ``` .repomix/ β”œβ”€β”€ context.json # Metadata and usage info @@ -198,7 +207,8 @@ Repomix consolidates your entire repository into a single AI-friendly file for c └── repomix-repo-TIMESTAMP.txt # Previous versions ``` -**Usage:** +**Usage:** + ```bash # Copy to AI tool cat .repomix/repomix-latest.txt | pbcopy @@ -210,7 +220,8 @@ repomix --token-count-tree 50 . wc -l .repomix/repomix-latest.txt ``` -**Aliases:** +**Aliases:** + ```bash jj repomix-update # Install/update hooks jj repomix-status # Show status @@ -270,11 +281,11 @@ jjConfig/ ## πŸ“œ Version History -| Version | Date | Description | -| --------- | ---------- | ----------------------------------- | -| v1.1.0 | 2025-11-07 | GitMCP integration, hooks, AI gen | -| v1.0.0 | 2025-11-01 | Synthwave84, aliases, references | -| v0.1.0 | 2025-11-01 | Original basic config | +| Version | Date | Description | +| ------- | ---------- | --------------------------------- | +| v1.1.0 | 2025-11-07 | GitMCP integration, hooks, AI gen | +| v1.0.0 | 2025-11-01 | Synthwave84, aliases, references | +| v0.1.0 | 2025-11-01 | Original basic config | Full changelog: [`backups/VERSION_HISTORY.md`](backups/VERSION_HISTORY.md) Roadmap: [`TASKS.md`](TASKS.md) @@ -283,7 +294,8 @@ Roadmap: [`TASKS.md`](TASKS.md) ## 🀝 Contributing -Contributions welcome! +Contributions welcome! + - See [`CONTRIBUTING.md`](CONTRIBUTING.md) for setup, backups, code style, PR process. --- @@ -291,6 +303,7 @@ Contributions welcome! ## πŸ› Troubleshooting See [`TROUBLESHOOTING.md`](TROUBLESHOOTING.md) for common issues: + - Installation - Symlinks - GitMCP hook failures @@ -308,7 +321,7 @@ MIT License. See [LICENSE](LICENSE). ## πŸ‘€ Author **Thomo1318** -Email: +Email: GitHub: [@Thomo1318](https://github.com/Thomo1318) --- diff --git a/TASKS.md b/TASKS.md index 557af4f..b88d7ce 100644 --- a/TASKS.md +++ b/TASKS.md @@ -3,6 +3,7 @@ ## Immediate Tasks ### TASK 1: Evaluate Pager Configuration + **Priority:** Medium **Version:** v1.1.0-pager **Status:** Pending @@ -11,23 +12,50 @@ **Action:** Test in daily use, consider alternatives (delta, bat, diff-so-fancy) **Reference:** `ui-configs/tier3-advanced-ui.toml` +### TASK 2: Audit Trunk Configuration + +**Priority:** High +**Status:** Pending +**Action:** Investigate `trunk check` autofix behavior (caused brace corruption in shell scripts). Ensure `.trunk/trunk.yaml` is configured for safety (Gold Standard). + +### TASK 3: Documentation Overhaul + +**Priority:** High +**Status:** Pending +**Action:** Consolidate fragmented READMEs, fix broken links, standardize formatting, and improve navigation. +**Reference:** `documentation_audit.md` + +### TASK 4: Docs Site Generation + +**Priority:** Medium +**Status:** Planned +**Action:** Evaluate and implement a static site generator (e.g., MkDocs) for project documentation. + +### TASK 5: Update Roadmap + +**Priority:** Medium +**Status:** Pending +**Action:** Review and refine the project roadmap (TASKS.md, VERSION_HISTORY.md) to ensure it reflects current priorities and completed work. + --- ## Future Version Tasks ### v2.0.0-formatters - Code Formatters & Linters + **Priority:** High **Status:** Planned **Tools to Integrate:** -- [ ] Ruff (Python linter/formatter) -- [ ] Prettier (JS/TS/JSON/MD formatter) -- [ ] MegaLinter (https://github.com/oxsecurity/megalinter) + +- [x] Ruff (Configured in Trunk) +- [x] Prettier (Configured in Trunk) +- [x] MegaLinter (Skipped - using Trunk) - [ ] python-lsp (Language server) - [ ] pylint (Python linter) - [ ] black (Python formatter) - [ ] pyright (Python type checker) -- [ ] Trunk.io (https://trunk.io/) +- [x] Trunk.io (Implemented v1.2.0) **Configuration Section:** `[fix.tools]` **Reference:** `ui-configs/tier3-advanced-ui.toml` @@ -35,12 +63,14 @@ --- ### v3.0.0-conventional - Conventional Commits + **Priority:** Medium **Status:** Planned **Spec:** https://www.conventionalcommits.org/en/v1.0.0/ **Implementation:** + - [ ] Commit message templates - [ ] Validation hooks - [ ] Changelog generation @@ -51,16 +81,19 @@ --- ### v4.0.0-release-automation - Release Management + **Priority:** Medium **Status:** Planned **Tool Options (Choose ONE):** + - [ ] release-please (https://github.com/googleapis/release-please) - [ ] semantic-release (https://github.com/semantic-release/semantic-release) - [ ] GitVersion (https://github.com/GitTools/GitVersion) - [ ] release-it (https://github.com/release-it/release-it) **Features:** + - Automated version bumping - Changelog generation - GitHub release creation @@ -69,15 +102,18 @@ --- ### v5.0.0-cicd - CI/CD Integration + **Priority:** High **Status:** Planned **Platforms:** + - [ ] GitHub Actions - [ ] CircleCI (https://circleci.com/) - [ ] Jenkins (https://www.jenkins.io/) **Workflows:** + - Automated testing - Code quality checks - Security scanning @@ -86,20 +122,23 @@ --- ### v6.0.0-security - Security & Code Quality + **Priority:** High **Status:** Planned **Tools to Integrate:** -- [ ] GitGuardian ggshield (https://www.gitguardian.com/ggshield) -- [ ] Snyk (https://snyk.io/) -- [ ] Semgrep (https://semgrep.dev/) -- [ ] Trivy (https://trivy.dev/latest/) + +- [x] GitGuardian ggshield (Implemented v1.2.0) +- [ ] Snyk (Deferred to agent rules) +- [ ] Semgrep (via Trunk) +- [ ] Trivy (via Trunk) - [ ] SonarQube (https://www.sonarsource.com/products/sonarqube/) - [ ] Checkmarx (https://checkmarx.com/) - [ ] CodeScene-CE (https://codescene.com/product/codescene-for-open-source) - [ ] Task (https://github.com/go-task/task) **Integration Points:** + - Pre-commit hooks - CI/CD pipelines - IDE integration @@ -110,18 +149,21 @@ ## Task Tracking ### Completed + - [x] v0.1.0 - Original config backup - [x] v1.0.0 - Optimized configuration with Synthwave84 ### In Progress + - [ ] v1.1.0 - Pager evaluation ### Planned -- [ ] v2.0.0 - Code formatters + +- [x] v2.0.0 - Code formatters (Trunk.io integrated) - [ ] v3.0.0 - Conventional commits - [ ] v4.0.0 - Release automation - [ ] v5.0.0 - CI/CD integration -- [ ] v6.0.0 - Security tools +- [x] v6.0.0 - Security tools (Partially Implemented v1.2.0) --- @@ -137,6 +179,7 @@ ## TODO Items ### TODO 1: Assess Raycast AI MCP Integration + **Priority:** Medium **Version:** TBD **Status:** Research needed @@ -144,6 +187,7 @@ **Question:** Can Raycast AI automatically use `.mcp/context.json` files for repo context? **Action Items:** + - [ ] Check Raycast AI documentation for MCP support - [ ] Test if Raycast AI can read local `.mcp/` files - [ ] Determine if manual configuration needed @@ -151,25 +195,28 @@ - [ ] If supported: Document configuration steps **Current State:** + - GitMCP integration creates `.mcp/context.json` locally - Works with Cursor IDE, Claude Desktop (confirmed) - Raycast AI compatibility: **UNKNOWN** **Fallback:** + - Use context files as reference in prompts - Copy `.mcp/README.md` content when needed - Use MCP-compatible tools (Cursor, Claude) for AI-assisted development -**Reference:** +**Reference:** + - GitMCP article: https://medium.com/the-context-layer/stop-letting-ai-guess-your-code-instantly-make-every-github-repo-ai-savvy-with-this-one-liner-cc23e00c9ea2 - Raycast AI docs: https://developers.raycast.com/ - --- ## GitHub Integration TODO ### TODO 4: GitHub CLI Integration with Interactive Prompts + **Priority:** High **Version:** v1.1.1-gh-integration **Status:** βœ… Implemented @@ -179,6 +226,7 @@ **Implementation:** External script approach (recommended in Task4.md analysis) **Features Implemented:** + - [x] Interactive repo creation with prompts - [x] Auto-generate description from repo content (README.md, package.json, pyproject.toml, Cargo.toml) - [x] Choose public/private visibility @@ -193,6 +241,7 @@ **Implemented Solution:** **File Structure:** + ``` ~/.config/jj/ β”œβ”€β”€ scripts/ @@ -227,15 +276,15 @@ jj gh-clone https://github.com/owner/repo **Key Improvements Over Original Plan:** -| Feature | Original Plan | Implemented Solution | -|---------|--------------|---------------------| -| Error Handling | Minimal (`set -e`) | Comprehensive validation | -| Username | Hardcoded "Thomo1318" | Dynamic via `gh api user` | -| Description | Basic README check | Multi-source (README, package.json, etc.) | -| Maintainability | Inline bash (hard to edit) | Separate script file | -| UX | Plain text | Colored output, progress indicators | -| Testing | Difficult | Easy to test independently | -| Dependencies | No checking | Validates gh, jj, git, auth status | +| Feature | Original Plan | Implemented Solution | +| --------------- | -------------------------- | ----------------------------------------- | +| Error Handling | Minimal (`set -e`) | Comprehensive validation | +| Username | Hardcoded "Thomo1318" | Dynamic via `gh api user` | +| Description | Basic README check | Multi-source (README, package.json, etc.) | +| Maintainability | Inline bash (hard to edit) | Separate script file | +| UX | Plain text | Colored output, progress indicators | +| Testing | Difficult | Easy to test independently | +| Dependencies | No checking | Validates gh, jj, git, auth status | **Installation Steps:** @@ -257,12 +306,13 @@ gh auth status || gh auth login ``` **Testing Results:** + - βœ… Help command works - βœ… Script is executable - βœ… All dependencies available (gh, jj, git) - βœ… Invalid command handling works - βœ… Auto-description generation works -- ⚠️ Interactive tests require GitHub authentication +- ⚠️ Interactive tests require GitHub authentication **Commit Signing Integration:** @@ -277,6 +327,7 @@ key = "~/.ssh/id_ed25519" ``` **Reference:** + - GitHub CLI: https://cli.github.com/ - SSH signing: https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification - jj signing docs: https://jj-vcs.github.io/jj/latest/config/#signing diff --git a/backups/VERSION_HISTORY.md b/backups/VERSION_HISTORY.md index d43cc36..017985c 100644 --- a/backups/VERSION_HISTORY.md +++ b/backups/VERSION_HISTORY.md @@ -1,25 +1,47 @@ # JJ Configuration Version History ## v0.1.0-original (2025-11-01) + **Location:** `backups/v0.1.0-original/` **Status:** Superseded **Description:** Original basic configuration before optimization **Contents:** + - name, email, color at root level (incorrect structure) - No aliases, templates, or customizations +- name, email, color at root level (incorrect structure) + +--- + +## v1.2.0-security (2026-01-01) + +**Location:** `backups/v1.2.0-security/` (TBD) +**Status:** In Development +**Description:** Major security and quality hardening release. + +**Key Features:** + +- **Safety Net**: `pre-push` hook with PII grep + GitGuardian scanning +- **Code Quality**: Trunk.io integration (Prettier, Shellcheck, etc.) +- **AI Review**: `scripts/ai-review.sh` for on-demand CodeRabbit analysis +- **Workflow**: Automated `/publish-change` agent workflow +- **Automation**: `sanitize_email.py` auto-discovery --- ## v1.0.0-optimized (2025-11-01) ← CURRENT + **Location:** `backups/v1.0.0-optimized/` **Status:** Active **Description:** Comprehensive optimization with all 13 approved changes **Breaking Changes:** + - Fixed TOML structure (moved settings to proper sections) **New Features:** + - jj-fzf TUI integration - Synthwave84 color scheme (30+ colors) - 15 starter aliases @@ -35,37 +57,47 @@ ## Future Versions (Planned) ### v2.0.0-formatters + **Status:** Planned **Description:** Code formatters and linters + - [fix.tools] for Ruff, Prettier, Black, Pyright - MegaLinter integration - Trunk.io integration - python-lsp, pylint ### v3.0.0-conventional + **Status:** Planned **Description:** Conventional Commits integration + - Commit message templates - Conventional Commits spec compliance - Auto-generated changelogs ### v4.0.0-release-automation + **Status:** Planned **Description:** Release automation tooling + - release-please OR semantic-release OR GitVersion OR release-it - Automated version bumping - Changelog generation ### v5.0.0-cicd + **Status:** Planned **Description:** CI/CD pipeline integration + - GitHub Actions workflows - CircleCI configuration - Jenkins integration ### v6.0.0-security + **Status:** Planned **Description:** Security and code quality tools + - GitGuardian ggshield - Snyk, Semgrep, Trivy - SonarQube, Checkmarx, CodeScene @@ -75,17 +107,20 @@ ## Future Tasks & Enhancements ### v1.1.0-pager (Next Minor Release) + **Status:** Planned **Priority:** Medium **Description:** Evaluate and potentially change pager configuration **Current Setting:** + ```toml [ui] pager = \":builtin\" ``` **Alternatives to Consider:** + - **delta** - Syntax-highlighted diffs with side-by-side view ```toml pager = [\"delta\", \"--line-numbers\", \"--navigate\", \"--side-by-side\"] @@ -104,10 +139,10 @@ pager = \":builtin\" ``` **Decision Points:** + - Test builtin pager first in daily use - Evaluate if external pager provides better UX - Consider installation requirements - Check performance with large diffs **Reference:** `~/.config/jj/ui-configs/tier3-advanced-ui.toml` - diff --git a/backups/v1.1.0-mcp-integration/config.toml b/backups/v1.1.0-mcp-integration/config.toml index 093696e..c72fd14 100644 --- a/backups/v1.1.0-mcp-integration/config.toml +++ b/backups/v1.1.0-mcp-integration/config.toml @@ -105,7 +105,13 @@ tui = ["!lazyjj"] ui = ["!gg"] # Repository Initialization (v1.1.0 - MCP-enabled by default) -init = ["util", "exec", "--", "bash", "-c", ''' +init = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e echo "Initializing jj repository with GitMCP integration..." @@ -143,10 +149,17 @@ if [ -n "$REMOTE" ]; then else echo "β„Ή Local repo - MCP context generated for local use" fi -'''] +''', +] # Short version (same as init) -i = ["util", "exec", "--", "bash", "-c", ''' +i = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e jj git init --colocate mkdir -p .git/hooks @@ -157,13 +170,20 @@ chmod +x .git/hooks/post-* .git/hooks/post-commit REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") [ -n "$REMOTE" ] && echo "GitMCP: https://gitmcp.io/$REMOTE" || echo "Local repo initialized" -'''] +''', +] # Initialize without MCP (fallback) init-simple = ["git", "init", "--colocate"] # Install MCP hooks in existing repo -mcp-update = ["util", "exec", "--", "bash", "-c", ''' +mcp-update = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' set -e echo "Installing GitMCP hooks in existing repository..." @@ -180,10 +200,17 @@ chmod +x .git/hooks/post-* echo "βœ“ GitMCP hooks installed" REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") [ -n "$REMOTE" ] && echo "βœ“ GitMCP URL: https://gitmcp.io/$REMOTE" -'''] +''', +] # Show GitMCP URL for current repo -mcp-url = ["util", "exec", "--", "bash", "-c", ''' +mcp-url = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") if [ -n "$REMOTE" ]; then echo "GitMCP URL: https://gitmcp.io/$REMOTE" @@ -195,17 +222,25 @@ if [ -n "$REMOTE" ]; then else echo "Not a GitHub repository" fi -'''] +''', +] # Open GitMCP URL in browser -mcp-open = ["util", "exec", "--", "bash", "-c", ''' +mcp-open = [ + "util", + "exec", + "--", + "bash", + "-c", + ''' REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") if [ -n "$REMOTE" ]; then open "https://gitmcp.io/$REMOTE" else echo "Not a GitHub repository" fi -'''] +''', +] # Synthwave84 Color Scheme [colors] diff --git a/config-v1.1.0-draft.toml b/config-v1.1.0-draft.toml index fc0100c..5e6fcf8 100644 --- a/config-v1.1.0-draft.toml +++ b/config-v1.1.0-draft.toml @@ -22,14 +22,35 @@ email = "steele.thompson13@gmail.com" # UI Settings [ui] editor = "micro" +# Use diff-so-fancy via a wrapper script or pipe, but for a true editor integration, 'delta' is often preferred in terminals. +# Since you have delta/diff-so-fancy, let's configure delta as the pager for diffs which is the standard "optimal" way. +# For the actual 3-pane diff editor, use a GUI or keep jj-fzf? keeping jj-fzf as diff-editor for now. diff-editor = "jj-fzf" diff-formatter = ":color-words" +# Better conflict markers +conflict-marker-style = "snapshot" +# Optimal Pager: Delta (Syntax highlighting for diffs) +pager = "delta" graph.style = "curved" -pager = ":builtin" log-word-wrap = true default-command = ["log"] color = "always" +[ui.diff] +tool = "difft" # Use difftastic by default for 'jj diff' content + +# Core Settings +[core] +fsmonitor = "watchman" # Instant file updates + +# Merge Tools - Difftastic (Semantic Diff) +[merge-tools] +difft = { program = "difft", diff-args = ["--color=always", "$left", "$right"] } + +# Snapshot Safety +[snapshot] +max-new-file-size = "10MiB" + # Git Integration [git] push-new-bookmarks = true @@ -48,7 +69,7 @@ git_push_bookmark = '"Thomo1318/push-" ++ change_id.short()' [template-aliases] 'format_short_id(id)' = "id.shortest()" 'format_short_change_id(id)' = "format_short_id(id)" -'format_timestamp(timestamp)' = "timestamp.ago()" +'format_timestamp(timestamp)' = 'timestamp.format("%Y-%m-%d %H:%M")' 'format_short_signature(signature)' = "signature.email().local()" 'format_short_operation_id(id)' = "id.shortest()" 'format_field(key, value)' = 'key ++ ": " ++ value ++ "\n"' @@ -223,10 +244,15 @@ mcp-open = [ ''' REMOTE=$(git remote get-url origin 2>/dev/null | sed "s/.*github.com[:/]//" | sed "s/.git$//" || echo "") if [ -n "$REMOTE" ]; then - open "https://gitmcp.io/$REMOTE" -else - echo "Not a GitHub repository" -fi + if command -v python3 >/dev/null 2>&1; then + python3 -m webbrowser "https://gitmcp.io/$REMOTE" + elif command -v open >/dev/null 2>&1; then + open "https://gitmcp.io/$REMOTE" + elif command -v xdg-open >/dev/null 2>&1; then + xdg-open "https://gitmcp.io/$REMOTE" + else + echo "Please open: https://gitmcp.io/$REMOTE" + fi ''', ] diff --git a/scripts/ai-review.sh b/scripts/ai-review.sh index 73dc131..eee54a7 100755 --- a/scripts/ai-review.sh +++ b/scripts/ai-review.sh @@ -12,27 +12,27 @@ if ! command -v coderabbit &> /dev/null; then exit 1 fi -echo "🐰 Rabbit Check: Analyzing $TYPE changes..." +echo "🐰 Rabbit Check: Analyzing ${TYPE} changes..." echo "----------------------------------------" # 2. Run CodeRabbit in Machine-Readable mode (--prompt-only) # We capture stderr to check for "No files found" which is not a real error for us. -OUTPUT=$(coderabbit review --prompt-only -t "$TYPE" 2>&1) +OUTPUT=$(coderabbit review --prompt-only -t "${TYPE}" 2>&1) EXIT_CODE=$? # 3. Handle Output -if [[ $EXIT_CODE -ne 0 ]]; then - if echo "$OUTPUT" | grep -q "No files found"; then +if [[ ${EXIT_CODE} -ne 0 ]]; then + if echo "${OUTPUT}" | grep -q "No files found"; then echo "βœ… Clean State: No changes found to review." exit 0 else echo "❌ Review Failed:" - echo "$OUTPUT" - exit $EXIT_CODE + echo "${OUTPUT}" + exit "${EXIT_CODE}" fi fi # 4. Success - Print the AI Analysis -echo "$OUTPUT" +echo "${OUTPUT}" echo "----------------------------------------" echo "βœ… Analysis Complete." diff --git a/templates/security-hooks/pre-commit b/templates/security-hooks/pre-commit index 46620d8..872f23d 100755 --- a/templates/security-hooks/pre-commit +++ b/templates/security-hooks/pre-commit @@ -6,23 +6,24 @@ set -e # Check if sanitization script exists -if [ ! -f .build-artifacts/sanitize_all.py ]; then - exit 0 +if [ ! -f .build-artifacts/sanitize_email.py ]; then + echo "⚠️ Sanitization script not found. Skipping." + exit 0 fi # Only sanitize if we're about to commit files with real email if git diff --cached --name-only | grep -qE "(config\.toml|README\.md|QUICKSTART\.md|TASKS\.md)"; then - if git diff --cached | grep -q "steele.thompson13@gmail.com"; then - echo "πŸ”’ Sanitizing emails before commit..." - - # Run sanitization - python3 .build-artifacts/sanitize_all.py - - # Re-stage sanitized files - git add -u - - echo "βœ… Files sanitized for commit" - fi + if git diff --cached | grep -q "steele.thompson13@gmail.com"; then + echo "πŸ”’ Sanitizing emails before commit..." + + # Run sanitization + python3 .build-artifacts/sanitize_email.py + + # Re-stage sanitized files + git add -u + + echo "βœ… Files sanitized for commit" + fi fi exit 0