Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
807498f777 | |||
a35972318e | |||
83df3f84d0 | |||
5c8b8d2f0f | |||
7a0d72405f | |||
05b147af25 | |||
9d957385ee | |||
81ce027e8d |
1
.cuddle/base
Submodule
1
.cuddle/base
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 985556ea80a0051c56eddddbf6bdab99235db949
|
148
.cuddle/tmp/cuddle-rust-cli-plan.yaml
Normal file
148
.cuddle/tmp/cuddle-rust-cli-plan.yaml
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
kind: pipeline
|
||||||
|
name: cuddle-rust-cli-plan
|
||||||
|
type: docker
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: load_secret
|
||||||
|
image: debian:buster-slim
|
||||||
|
volumes:
|
||||||
|
- name: ssh
|
||||||
|
path: /root/.ssh/
|
||||||
|
environment:
|
||||||
|
SSH_KEY:
|
||||||
|
from_secret: gitea_id_ed25519
|
||||||
|
commands:
|
||||||
|
- mkdir -p $HOME/.ssh/
|
||||||
|
- echo "$SSH_KEY" | base64 -d > $HOME/.ssh/id_ed25519
|
||||||
|
- chmod -R 600 ~/.ssh
|
||||||
|
- |
|
||||||
|
cat >$HOME/.ssh/config <<EOL
|
||||||
|
Host git.front.kjuulh.io
|
||||||
|
IdentityFile $HOME/.ssh/id_ed25519
|
||||||
|
IdentitiesOnly yes
|
||||||
|
UserKnownHostsFile=/dev/null
|
||||||
|
StrictHostKeyChecking no
|
||||||
|
EOL
|
||||||
|
- chmod 700 ~/.ssh/config
|
||||||
|
|
||||||
|
- name: build pr
|
||||||
|
image: kasperhermansen/{{bin_name}}:{{image_tag}}
|
||||||
|
volumes:
|
||||||
|
- name: ssh
|
||||||
|
path: /root/.ssh/
|
||||||
|
commands:
|
||||||
|
- eval `ssh-agent`
|
||||||
|
- ssh-add
|
||||||
|
- echo "$DOCKER_PASSWORD" | docker login --password-stdin --username="$DOCKER_USERNAME" docker.io
|
||||||
|
- export CLUSTER=clank-dev
|
||||||
|
- cuddle --version
|
||||||
|
- {{ bin_name }} pr
|
||||||
|
environment:
|
||||||
|
DAGGER_CLOUD_TOKEN:
|
||||||
|
from_secret: dagger_cloud_token
|
||||||
|
DRONE_HOST: "https://ci.i.kjuulh.io"
|
||||||
|
DRONE_USER: "kjuulh"
|
||||||
|
DRONE_TOKEN:
|
||||||
|
from_secret: drone_token
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
DOCKER_PASSWORD:
|
||||||
|
from_secret: docker_password
|
||||||
|
DOCKER_USERNAME:
|
||||||
|
from_secret: docker_username
|
||||||
|
CUDDLE_SSH_AGENT: "true"
|
||||||
|
CI_PREFIX: "/mnt/ci/ci"
|
||||||
|
DOCKER_HOST: "tcp://192.168.1.155:2376"
|
||||||
|
CUDDLE_PLEASE_TOKEN:
|
||||||
|
from_secret: cuddle_please_token
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- pull_request
|
||||||
|
exclude:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
depends_on:
|
||||||
|
- "load_secret"
|
||||||
|
|
||||||
|
- name: build main
|
||||||
|
image: kasperhermansen/{{bin_name}}:{{image_tag}}
|
||||||
|
volumes:
|
||||||
|
- name: ssh
|
||||||
|
path: /root/.ssh/
|
||||||
|
commands:
|
||||||
|
- eval `ssh-agent`
|
||||||
|
- ssh-add
|
||||||
|
- echo "$DOCKER_PASSWORD" | docker login --password-stdin --username="$DOCKER_USERNAME" docker.io
|
||||||
|
- export CLUSTER=clank-prod
|
||||||
|
- cuddle --version
|
||||||
|
- {{ bin_name }} main
|
||||||
|
environment:
|
||||||
|
DAGGER_CLOUD_TOKEN:
|
||||||
|
from_secret: dagger_cloud_token
|
||||||
|
DRONE_HOST: "https://ci.i.kjuulh.io"
|
||||||
|
DRONE_USER: "kjuulh"
|
||||||
|
DRONE_TOKEN:
|
||||||
|
from_secret: drone_token
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
DOCKER_PASSWORD:
|
||||||
|
from_secret: docker_password
|
||||||
|
DOCKER_USERNAME:
|
||||||
|
from_secret: docker_username
|
||||||
|
CUDDLE_SSH_AGENT: "true"
|
||||||
|
CI_PREFIX: "/mnt/ci/ci"
|
||||||
|
DOCKER_HOST: "tcp://192.168.1.155:2376"
|
||||||
|
CUDDLE_PLEASE_TOKEN:
|
||||||
|
from_secret: cuddle_please_token
|
||||||
|
when:
|
||||||
|
event:
|
||||||
|
- push
|
||||||
|
branch:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
exclude:
|
||||||
|
- pull_request
|
||||||
|
depends_on:
|
||||||
|
- "load_secret"
|
||||||
|
|
||||||
|
- name: release
|
||||||
|
image: kasperhermansen/{{bin_name}}:{{image_tag}}
|
||||||
|
volumes:
|
||||||
|
- name: ssh
|
||||||
|
path: /root/.ssh/
|
||||||
|
commands:
|
||||||
|
- eval `ssh-agent`
|
||||||
|
- ssh-add
|
||||||
|
- echo "$DOCKER_PASSWORD" | docker login --password-stdin --username="$DOCKER_USERNAME" docker.io
|
||||||
|
- export CLUSTER=clank-prod
|
||||||
|
- cuddle --version
|
||||||
|
- {{ bin_name }} release
|
||||||
|
environment:
|
||||||
|
DAGGER_CLOUD_TOKEN:
|
||||||
|
from_secret: dagger_cloud_token
|
||||||
|
DRONE_HOST: "https://ci.i.kjuulh.io"
|
||||||
|
DRONE_USER: "kjuulh"
|
||||||
|
DRONE_TOKEN:
|
||||||
|
from_secret: drone_token
|
||||||
|
DOCKER_BUILDKIT: 1
|
||||||
|
DOCKER_PASSWORD:
|
||||||
|
from_secret: docker_password
|
||||||
|
DOCKER_USERNAME:
|
||||||
|
from_secret: docker_username
|
||||||
|
CUDDLE_SSH_AGENT: "true"
|
||||||
|
GIT_PASSWORD:
|
||||||
|
from_secret: git_password
|
||||||
|
CI_PREFIX: "/mnt/ci/ci"
|
||||||
|
DOCKER_HOST: "tcp://192.168.1.155:2376"
|
||||||
|
CUDDLE_PLEASE_TOKEN:
|
||||||
|
from_secret: cuddle_please_token
|
||||||
|
CRATES_IO_TOKEN:
|
||||||
|
from_secret: crate_io_token
|
||||||
|
when:
|
||||||
|
ref:
|
||||||
|
- refs/tags/v*
|
||||||
|
depends_on:
|
||||||
|
- "load_secret"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: ssh
|
||||||
|
temp: {}
|
||||||
|
|
23
CHANGELOG.md
Normal file
23
CHANGELOG.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Changelog
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [0.1.3] - 2025-07-06
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- add readme license and more
|
||||||
|
|
||||||
|
## [0.1.2] - 2025-07-06
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- add readme
|
||||||
|
- try again
|
||||||
|
|
||||||
|
## [0.1.1] - 2025-07-06
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- with publish
|
@ -3,5 +3,5 @@ members = ["crates/*"]
|
|||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.0.1"
|
version = "0.1.3"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
171
README.md
Normal file
171
README.md
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
# nossh
|
||||||
|
|
||||||
|
A lightning-fast SSH endpoint finder and launcher with fuzzy history lookup and ⬢ `.ssh/config` reference.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Fuzzy history search**
|
||||||
|
Quickly fuzzy-find and re-run past `ssh` commands you’ve executed.
|
||||||
|
|
||||||
|
- **`.ssh/config` lookup**
|
||||||
|
Instantly search host entries from your `~/.ssh/config`.
|
||||||
|
|
||||||
|
- **Interactive mode**
|
||||||
|
Presents a searchable list of endpoints for one-shot selection.
|
||||||
|
|
||||||
|
- **External invocation**
|
||||||
|
Falls back to standard `ssh` when provided arguments.
|
||||||
|
|
||||||
|
- **Configurable config path**
|
||||||
|
Override the default `~/.ssh/config` via an `--ssh-config-path` flag or `SSH_CONFIG_PATH` env var.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo install nossh
|
||||||
|
````
|
||||||
|
|
||||||
|
Or build from source:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/yourorg/nossh.git
|
||||||
|
cd nossh
|
||||||
|
cargo build --release
|
||||||
|
cp target/release/nossh /usr/local/bin/
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quickstart
|
||||||
|
|
||||||
|
1. **Launch interactive search**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nossh
|
||||||
|
```
|
||||||
|
|
||||||
|
* Fuzzy-find against:
|
||||||
|
|
||||||
|
* Your cached history of `ssh …` commands.
|
||||||
|
* Host entries in your `~/.ssh/config`.
|
||||||
|
|
||||||
|
2. **Run a past command or config entry**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start typing “git.fr” and press Enter:
|
||||||
|
$ nossh
|
||||||
|
1. ratchet:22
|
||||||
|
2. somegateway:222
|
||||||
|
# 3. git.front.kjuulh.io
|
||||||
|
> git.fr
|
||||||
|
# then Enter runs:
|
||||||
|
ssh git.front.kjuulh.io
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Direct `ssh` passthrough**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nossh user@host -p 2222
|
||||||
|
```
|
||||||
|
|
||||||
|
Behaves exactly like `ssh …`; also logs the invocation for future fuzzy lookup.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```text
|
||||||
|
nossh [--ssh-config-path <path>] [<ssh-args>...]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Option | Description |
|
||||||
|
| ------------------------ | ---------------------------------------------------------------------------------------------- |
|
||||||
|
| `--ssh-config-path PATH` | Path to your SSH `config` file (default: `~/.ssh/config`). Overrides `SSH_CONFIG_PATH` env var |
|
||||||
|
| `<ssh-args>…` | If provided, forwarded to `ssh` as normal. |
|
||||||
|
|
||||||
|
### Environment
|
||||||
|
|
||||||
|
* `SSH_CONFIG_PATH`
|
||||||
|
Alternative way to point to your SSH config:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export SSH_CONFIG_PATH="/custom/path/config"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The default SSH config path is `${HOME}/.ssh/config`. If that file is missing or you wish to use a different config, set the flag or env var:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nossh --ssh-config-path /mnt/shared/ssh_config
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
1. **Startup**
|
||||||
|
|
||||||
|
* Reads `~/.ssh/config` (or your override).
|
||||||
|
* Loads your SSH‐command history database (`~/.local/share/nossh/db.sqlite3`).
|
||||||
|
|
||||||
|
2. **Interactive Mode**
|
||||||
|
|
||||||
|
* Presents a fuzzy prompt (via `fzf`-style) combining:
|
||||||
|
|
||||||
|
* Host patterns from config.
|
||||||
|
* Host strings from history (e.g. `user@host -p 2222`).
|
||||||
|
|
||||||
|
3. **Selection**
|
||||||
|
|
||||||
|
* On Enter, launches `ssh` with the selected arguments.
|
||||||
|
* In external (non-interactive) mode, simply proxies `ssh …` and appends to history.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
* **Basic interactive**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nossh
|
||||||
|
```
|
||||||
|
|
||||||
|
* **Forced interactive**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nossh interactive
|
||||||
|
```
|
||||||
|
|
||||||
|
* **One-liner passthrough**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nossh -i ~/.ssh/id_ed25519 root@example.com
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
Clone and run tests:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/kjuulh/nossh.git
|
||||||
|
cd nossh
|
||||||
|
cargo test
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT-licensed
|
||||||
|
|
||||||
|
```
|
||||||
|
|
@ -1,8 +1,12 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "nossh"
|
name = "nossh"
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
readme = "../../README.md"
|
||||||
|
version.workspace = true
|
||||||
|
license.workspace = true
|
||||||
|
repository = "https://git.front.kjuulh.io/kjuulh/nossh"
|
||||||
|
authors = ["kjuulh <contact@kasperhermansen.com>"]
|
||||||
|
description = "A SSH endpoint finder and launcher with fuzzy history lookup and ⬢ `.ssh/config` reference."
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
|
@ -6,6 +6,9 @@ vars:
|
|||||||
service: "nossh"
|
service: "nossh"
|
||||||
registry: kasperhermansen
|
registry: kasperhermansen
|
||||||
|
|
||||||
|
rust:
|
||||||
|
publish: {}
|
||||||
|
|
||||||
please:
|
please:
|
||||||
project:
|
project:
|
||||||
owner: kjuulh
|
owner: kjuulh
|
||||||
|
3
renovate.json
Normal file
3
renovate.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user