Browse Source

Sync from gitrepublic-web monorepo - 2026-02-25 09:44:48

Nostr-Signature: b97b2110557874521f3d7bb16293a1da5e62d78c092a5c0131caef26e8e99d6f 573634b648634cbad10f2451776089ea21090d9407f715e83c577b4611ae6edc 0158e672a19fdd63c540ba1e6f31ac1a8127d113ce066095ea3e67673a307582733ebcde3d9664bc92ec0a75a8d88c079f6a9129d4c3f174ce9d1fb238881714
master
Silberengel 3 weeks ago
parent
commit
00acaa2649
  1. 45
      README.md
  2. 112
      SYNC.md
  3. 133
      scripts/commands/repos.js
  4. 134
      scripts/git-wrapper.js
  5. 2
      scripts/gitrepublic.js

45
README.md

@ -16,31 +16,33 @@ export NOSTRGIT_SECRET_KEY="nsec1..."
# Setup (configures credential helper and commit hook) # Setup (configures credential helper and commit hook)
gitrep-setup gitrep-setup
# Use gitrepublic (or gitrep) for git operations # Use gitrepublic (or gitrep) for git operations and API access
gitrep clone https://your-domain.com/api/git/npub1.../repo.git gitrepublic-web # Run 'gitrep --help' for complete documentation and all available commands
gitrep push gitrepublic-web main
# Use gitrep for API commands too
gitrep push-all main # Push to all remotes
gitrep repos list # List repositories
gitrep publish repo-announcement myrepo
# Note: "gitrep" is a shorter alias for "gitrepublic" - both work the same way. # Note: "gitrep" is a shorter alias for "gitrepublic" - both work the same way.
# We suggest using "gitrepublic-web" as the remote name instead of "origin" # We suggest using "gitrepublic-web" as the remote name instead of "origin"
# because "origin" is often already set to GitHub, GitLab, or other services. # because "origin" is often already set to GitHub, GitLab, or other services.
``` ```
## Commands ## Documentation
- **`gitrepublic`** or **`gitrep`** - Unified command for both git operations and API access
- Git commands: `gitrep clone`, `gitrep push`, `gitrep pull`, etc.
- API commands: `gitrep push-all`, `gitrep repos list`, `gitrep publish`, etc.
- **`gitrepublic-setup`** or **`gitrep-setup`** - Automatic setup script
- **`gitrepublic-uninstall`** or **`gitrep-uninstall`** - Remove all configuration
> **Note**: `gitrep-api` and `gitrepublic-api` are still available for backward compatibility but are now aliases to `gitrep`/`gitrepublic`. For complete CLI documentation and all available commands, run:
```bash
gitrep --help
```
or
```bash
gitrepublic --help
```
Run any command with `--help` or `-h` for detailed usage information. This will show:
- Initial setup instructions
- All git commands
- All API commands
- Repository management
- Publishing Nostr events
- Environment variables
- And much more
## Uninstall ## Uninstall
@ -102,15 +104,6 @@ export GITREPUBLIC_PUBLISH_EVENT=true
export NOSTR_RELAYS="wss://relay1.com,wss://relay2.com" # Optional, has defaults export NOSTR_RELAYS="wss://relay1.com,wss://relay2.com" # Optional, has defaults
``` ```
## Documentation
For detailed documentation, run:
- `gitrep --help` or `gitrepublic --help` - General help and git commands
- `gitrep push-all --help` - Push to all remotes
- `gitrep repos --help` - Repository management
- `gitrep publish --help` - Publish Nostr events
- `gitrep-setup --help` or `gitrepublic-setup --help` - Setup options
- `gitrep-uninstall --help` or `gitrepublic-uninstall --help` - Uninstall options
## Links ## Links

112
SYNC.md

@ -1,112 +0,0 @@
# Syncing CLI to Separate Repository
This document explains how to keep the `gitrepublic-cli` in sync with a separate repository while maintaining it as part of the `gitrepublic-web` monorepo.
## When to Sync
You should sync the CLI to a separate repository when:
### 1. **Publishing to npm**
- Before publishing a new version to npm, sync to ensure the separate repo is up-to-date
- This allows users to install via `npm install -g gitrepublic-cli` from the published package
- The separate repo serves as the source of truth for npm package releases
### 2. **Independent Development & Contributions**
- When you want others to contribute to the CLI without needing access to the full web repo
- Allows CLI-specific issues, discussions, and pull requests
- Makes the CLI more discoverable as a standalone project
### 3. **Separate Release Cycle**
- If you want to version and release the CLI independently from the web application
- Allows different release cadences (e.g., CLI updates more frequently than the web app)
- Enables CLI-specific changelogs and release notes
### 4. **CI/CD & Automation**
- If you want separate CI/CD pipelines for the CLI (testing, linting, publishing)
- Allows automated npm publishing on version bumps
- Can set up separate GitHub Actions workflows for CLI-specific tasks
### 5. **Documentation & Discoverability**
- Makes the CLI easier to find for users who only need the CLI tools
- Allows separate documentation site or GitHub Pages
- Better SEO and discoverability on GitHub/npm
## When NOT to Sync
You typically don't need to sync if:
- You're only developing internally and not publishing to npm
- The CLI is tightly coupled to the web app and changes together
- You prefer keeping everything in one repository for simplicity
## Recommended Workflow
1. **Develop in monorepo**: Make all changes in `gitrepublic-cli/` within the main repo
2. **Sync before publishing**: Run `npm run cli:sync` before publishing to npm
3. **Publish from separate repo**: Publish to npm from the synced repository (or use CI/CD)
4. **Keep in sync**: Sync regularly to ensure the separate repo stays current
## Option 1: Git Subtree (Recommended)
Git subtree allows you to maintain the CLI as part of this repo while also syncing it to a separate repository.
### Initial Setup (One-time)
1. **Add the separate repo as a remote:**
```bash
cd /path/to/gitrepublic-web
git remote add cli-repo https://github.com/silberengel/gitrepublic-cli.git
```
2. **Push the CLI directory to the separate repo:**
```bash
git subtree push --prefix=gitrepublic-cli cli-repo main
```
### Syncing Changes
**To push changes from monorepo to separate repo:**
```bash
git subtree push --prefix=gitrepublic-cli cli-repo main
```
**To pull changes from separate repo to monorepo:**
```bash
git subtree pull --prefix=gitrepublic-cli cli-repo main --squash
```
### Publishing to npm
From the separate repository:
```bash
cd /path/to/gitrepublic-cli
npm publish
```
## Option 2: Manual Sync Script
A script is provided to help sync changes:
```bash
./scripts/sync-cli.sh
```
This script:
1. Copies changes from `gitrepublic-cli/` to a separate repo directory
2. Commits and pushes to the separate repo
3. Can be run after making CLI changes
## Option 3: GitHub Actions / CI
You can set up automated syncing using GitHub Actions. See `.github/workflows/sync-cli.yml` (if created).
## Publishing
The CLI can be published independently from npm:
```bash
cd gitrepublic-cli
npm version patch # or minor, major
npm publish
```
The CLI's `package.json` is configured to publish only the necessary files (scripts, README, LICENSE).

133
scripts/commands/repos.js

@ -206,7 +206,15 @@ export async function repos(args, server, json) {
} else { } else {
console.log(`Repository: ${npub}/${repo}`); console.log(`Repository: ${npub}/${repo}`);
console.log(`Description: ${data.description || 'No description'}`); console.log(`Description: ${data.description || 'No description'}`);
if (data.visibility) {
console.log(`Visibility: ${data.visibility}`);
} else {
// Backward compatibility: show private status if visibility not available
console.log(`Private: ${data.private ? 'Yes' : 'No'}`); console.log(`Private: ${data.private ? 'Yes' : 'No'}`);
}
if (data.projectRelays && data.projectRelays.length > 0) {
console.log(`Project Relays: ${data.projectRelays.join(', ')}`);
}
console.log(`Owner: ${data.owner || npub}`); console.log(`Owner: ${data.owner || npub}`);
if (cloneUrlReachability && cloneUrlReachability.length > 0) { if (cloneUrlReachability && cloneUrlReachability.length > 0) {
@ -221,21 +229,134 @@ export async function repos(args, server, json) {
} }
} else if (subcommand === 'settings' && args[1] && args[2]) { } else if (subcommand === 'settings' && args[1] && args[2]) {
const [npub, repo] = args.slice(1); const [npub, repo] = args.slice(1);
// Show help if requested
if (args[3] === '--help' || args[3] === '-h') {
console.log('Repository Settings:');
console.log('');
console.log('Get settings:');
console.log(' gitrep repos settings <npub> <repo>');
console.log('');
console.log('Update settings:');
console.log(' gitrep repos settings <npub> <repo> [options]');
console.log('');
console.log('Options:');
console.log(' --description <text> Update repository description');
console.log(' --visibility <level> Set visibility level');
console.log(' Values: public, unlisted, restricted, private');
console.log(' --project-relay <url> Add project relay (can be used multiple times)');
console.log(' Required for unlisted and restricted visibility');
console.log(' --private <true|false> (Deprecated) Use --visibility instead');
console.log('');
console.log('Visibility levels:');
console.log(' public - Repository and events published to all relays + project relay');
console.log(' unlisted - Repository public, events only to project relay');
console.log(' restricted - Repository private, events only to project relay');
console.log(' private - Repository private, no relay publishing (git-only)');
console.log('');
console.log('Examples:');
console.log(' gitrep repos settings npub1... myrepo --description "My repo"');
console.log(' gitrep repos settings npub1... myrepo --visibility unlisted --project-relay wss://relay.example.com');
console.log(' gitrep repos settings npub1... myrepo --visibility restricted --project-relay wss://relay1.com --project-relay wss://relay2.com');
process.exit(0);
}
if (args[3]) { if (args[3]) {
// Update settings // Update settings
const settings = {}; const settings = {};
for (let i = 3; i < args.length; i += 2) { const projectRelays = [];
const key = args[i].replace('--', '');
// Parse arguments - handle both --key value and --key=value formats
for (let i = 3; i < args.length; i++) {
const arg = args[i];
// Handle --key=value format
if (arg.includes('=')) {
const [key, value] = arg.split('=', 2);
const cleanKey = key.replace('--', '');
if (cleanKey === 'description') {
settings.description = value;
} else if (cleanKey === 'visibility') {
const vis = value.toLowerCase();
if (['public', 'unlisted', 'restricted', 'private'].includes(vis)) {
settings.visibility = vis;
} else {
console.error(`Error: Invalid visibility '${value}'. Must be one of: public, unlisted, restricted, private`);
process.exit(1);
}
} else if (cleanKey === 'project-relay') {
projectRelays.push(value);
} else if (cleanKey === 'private') {
// Backward compatibility: map private boolean to visibility
settings.visibility = value === 'true' ? 'restricted' : 'public';
}
} else if (arg.startsWith('--')) {
// Handle --key value format
const key = arg.replace('--', '');
const value = args[i + 1]; const value = args[i + 1];
if (key === 'description') settings.description = value;
else if (key === 'private') settings.private = value === 'true'; if (!value || value.startsWith('--')) {
console.error(`Error: Missing value for flag ${arg}`);
process.exit(1);
}
if (key === 'description') {
settings.description = value;
i++; // Skip next arg as it's the value
} else if (key === 'visibility') {
const vis = value.toLowerCase();
if (['public', 'unlisted', 'restricted', 'private'].includes(vis)) {
settings.visibility = vis;
} else {
console.error(`Error: Invalid visibility '${value}'. Must be one of: public, unlisted, restricted, private`);
process.exit(1);
} }
i++; // Skip next arg as it's the value
} else if (key === 'project-relay') {
projectRelays.push(value);
i++; // Skip next arg as it's the value
} else if (key === 'private') {
// Backward compatibility: map private boolean to visibility
settings.visibility = value === 'true' ? 'restricted' : 'public';
i++; // Skip next arg as it's the value
}
}
}
// Add project relays if any were specified
if (projectRelays.length > 0) {
settings.projectRelays = projectRelays;
}
const data = await apiRequest(server, `/repos/${npub}/${repo}/settings`, 'POST', settings); const data = await apiRequest(server, `/repos/${npub}/${repo}/settings`, 'POST', settings);
console.log(json ? JSON.stringify(data, null, 2) : 'Settings updated successfully'); if (json) {
console.log(JSON.stringify(data, null, 2));
} else {
console.log('Settings updated successfully');
console.log(` Description: ${data.description || 'No description'}`);
console.log(` Visibility: ${data.visibility || 'public'}`);
if (data.projectRelays && data.projectRelays.length > 0) {
console.log(` Project Relays: ${data.projectRelays.join(', ')}`);
}
}
} else { } else {
// Get settings // Get settings
const data = await apiRequest(server, `/repos/${npub}/${repo}/settings`, 'GET'); const data = await apiRequest(server, `/repos/${npub}/${repo}/settings`, 'GET');
console.log(json ? JSON.stringify(data, null, 2) : JSON.stringify(data, null, 2)); if (json) {
console.log(JSON.stringify(data, null, 2));
} else {
console.log(`Repository: ${npub}/${repo}`);
console.log(`Description: ${data.description || 'No description'}`);
console.log(`Visibility: ${data.visibility || 'public'}`);
if (data.projectRelays && data.projectRelays.length > 0) {
console.log(`Project Relays: ${data.projectRelays.join(', ')}`);
}
console.log(`Owner: ${data.owner || npub}`);
// Backward compatibility: show private status if visibility not available
if (!data.visibility && data.private !== undefined) {
console.log(`Private: ${data.private ? 'Yes' : 'No'}`);
}
}
} }
} else if (subcommand === 'maintainers' && args[1] && args[2]) { } else if (subcommand === 'maintainers' && args[1] && args[2]) {
const [npub, repo] = args.slice(1); const [npub, repo] = args.slice(1);

134
scripts/git-wrapper.js

@ -275,40 +275,138 @@ Usage:
gitrepublic <git-command> [arguments...] gitrepublic <git-command> [arguments...]
gitrep <git-command> [arguments...] (shorter alias) gitrep <git-command> [arguments...] (shorter alias)
Git Commands:
INITIAL SETUP
1. Install the CLI:
npm install -g gitrepublic-cli
2. Set your Nostr private key:
export NOSTRGIT_SECRET_KEY="nsec1..."
Or add to your shell profile (~/.bashrc, ~/.zshrc, etc.) for persistence:
echo 'export NOSTRGIT_SECRET_KEY="nsec1..."' >> ~/.bashrc
3. Run the setup script:
gitrep-setup
This will configure:
- Git credential helper (for automatic NIP-98 authentication)
- Commit signing hook (for automatic commit signatures)
Options:
--credential-only Only set up credential helper
--hook-only Only set up commit hook
--domain <domain> Configure for specific domain
--global-hook Install hook globally for all repos
4. (Optional) Configure server URL:
export GITREPUBLIC_SERVER="https://your-domain.com"
Or use --server flag with commands:
gitrep --server https://your-domain.com repos list
GIT COMMANDS
All standard git commands work:
gitrep clone https://domain.com/api/git/npub1.../repo.git gitrepublic-web gitrep clone https://domain.com/api/git/npub1.../repo.git gitrepublic-web
gitrep push gitrepublic-web main gitrep push gitrepublic-web main
gitrep pull gitrepublic-web main gitrep pull gitrepublic-web main
gitrep fetch gitrepublic-web gitrep fetch gitrepublic-web
gitrep branch gitrep branch
gitrep commit -m "My commit" gitrep commit -m "My commit"
gitrep status
gitrep log
API Commands: Note:
gitrep push-all [branch] [--force] [--tags] [--dry-run] Push to all remotes "gitrep" is a shorter alias for "gitrepublic" - both work the same way.
gitrep repos list List repositories
gitrep repos get <npub> <repo> Get repository info
gitrep publish <subcommand> Publish Nostr events
gitrep search <query> Search repositories
gitrep verify <event-file> Verify Nostr events
gitrep config [server] Show configuration
Note: "gitrep" is a shorter alias for "gitrepublic" - both work the same way.
We suggest using "gitrepublic-web" as the remote name instead of "origin" We suggest using "gitrepublic-web" as the remote name instead of "origin"
because "origin" is often already set to GitHub, GitLab, or other services. because "origin" is often already set to GitHub, GitLab, or other services.
Features:
- Works with all git commands (clone, push, pull, fetch, branch, merge, etc.) API COMMANDS
- Enhanced error messages for GitRepublic repositories
- Detailed authentication and permission error information
- Transparent pass-through for non-GitRepublic repositories (GitHub, GitLab, etc.) Repository Management:
- API commands for repository management and Nostr event publishing gitrep repos list List all repositories
gitrep repos get <npub> <repo> Get repository info with clone URLs
gitrep repos settings <npub> <repo> Get/update repository settings
gitrep repos settings <npub> <repo> \\
--visibility public \\
--project-relay wss://relay.example.com
gitrep repos maintainers <npub> <repo> Manage maintainers
gitrep repos branches <npub> <repo> List branches
gitrep repos tags <npub> <repo> List tags
gitrep repos fork <npub> <repo> Fork a repository
gitrep repos delete <npub> <repo> Delete a repository
File Operations:
gitrep file get <npub> <repo> <path> [branch] Get file content
gitrep file put <npub> <repo> <path> [file] Create/update file
gitrep file delete <npub> <repo> <path> Delete file
Publishing:
gitrep publish repo-announcement <repo> Publish repository announcement
gitrep publish pr <owner> <repo> <title> Create pull request
gitrep publish issue <owner> <repo> <title> Create issue
gitrep publish patch <owner> <repo> <file> Publish patch
gitrep publish --help Show all publish commands
Other:
gitrep push-all [branch] [--force] [--tags] Push to all remotes
gitrep pull-all [branch] [--merge] [--rebase] Fetch and merge from all remotes
gitrep search <query> Search repositories
gitrep verify <event-file> Verify Nostr event signatures
gitrep config [server] Show configuration
FEATURES
Git Operations:
Works with all git commands (clone, push, pull, fetch, branch, merge, etc.)
Enhanced error messages for GitRepublic repositories
Detailed authentication and permission error information
Transparent pass-through for non-GitRepublic repositories (GitHub, GitLab, etc.)
Automatic NIP-98 authentication via credential helper
Automatic commit signing with Nostr keys
API Access:
Full repository management from command line
Publish Nostr events (announcements, PRs, issues, patches)
Search and discover repositories
Manage maintainers and settings
Visibility control (public, unlisted, restricted, private)
For GitRepublic repositories, the wrapper provides: For GitRepublic repositories, the wrapper provides:
- Detailed 401/403 error messages with pubkeys and maintainer information - Detailed 401/403 error messages with pubkeys and maintainer information
- Helpful guidance on how to fix authentication issues - Helpful guidance on how to fix authentication issues
- Automatic fetching of error details from the server - Automatic fetching of error details from the server
- Automatic commit signing (if hook is installed)
ENVIRONMENT VARIABLES
Required:
NOSTRGIT_SECRET_KEY Nostr private key (nsec or hex) for authentication
Optional:
GITREPUBLIC_SERVER Default server URL (default: http://localhost:5173)
NOSTR_RELAYS Comma-separated relay URLs for publishing events
HELP & DOCUMENTATION
Run any command with --help for detailed usage information. Run any command with --help for detailed usage:
gitrep --help Show this help
gitrep repos --help Show repos command help
gitrep repos settings --help Show settings command help
gitrep publish --help Show publish command help
Documentation: https://github.com/silberengel/gitrepublic-cli Documentation: https://github.com/silberengel/gitrepublic-cli
GitCitadel: Visit us on GitHub: https://github.com/ShadowySupercode or on our homepage: https://gitcitadel.com GitCitadel: Visit us on GitHub: https://github.com/ShadowySupercode or on our homepage: https://gitcitadel.com

2
scripts/gitrepublic.js

@ -106,7 +106,7 @@ Commands:
config [server] Show configuration (server URL) config [server] Show configuration (server URL)
repos list List repositories repos list List repositories
repos get <npub> <repo> Get repository info with clone URL reachability (or use naddr: repos get <naddr>) repos get <npub> <repo> Get repository info with clone URL reachability (or use naddr: repos get <naddr>)
repos settings <npub> <repo> [--description <text>] [--private <true|false>] Get/update settings repos settings <npub> <repo> [--description <text>] [--visibility <level>] [--project-relay <url>] Get/update settings
repos maintainers <npub> <repo> [add|remove <npub>] Manage maintainers repos maintainers <npub> <repo> [add|remove <npub>] Manage maintainers
repos branches <npub> <repo> List branches repos branches <npub> <repo> List branches
repos tags <npub> <repo> List tags repos tags <npub> <repo> List tags

Loading…
Cancel
Save