mirror of
https://github.com/jbranchaud/til
synced 2026-10-31 16:23:27 +00:00
Compare commits
14
Commits
d9f4daa41d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
223602e525 | ||
|
|
bff11a2fee | ||
|
|
891e3453d1 | ||
|
|
2b29a572bb | ||
|
|
91a69640d8 | ||
|
|
0f143e71ed | ||
|
|
ae83a39fa8 | ||
|
|
c301401663 | ||
|
|
8129ad0eaa | ||
|
|
29676e0d5a | ||
|
|
dded5f6135 | ||
|
|
7ac2855666 | ||
|
|
861ef05330 | ||
|
|
5cff306092 |
@@ -10,7 +10,7 @@ working across different projects via [VisualMode](https://www.visualmode.dev/).
|
||||
|
||||
For a steady stream of TILs, [sign up for my newsletter](https://visualmode.kit.com/newsletter).
|
||||
|
||||
_1884 TILs and counting..._
|
||||
_1895 TILs and counting..._
|
||||
|
||||
See some of the other learning resources I work on:
|
||||
|
||||
@@ -59,6 +59,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
* [Kitty](#kitty)
|
||||
* [Linux](#linux)
|
||||
* [LLM](#llm)
|
||||
* [Logseq](#logseq)
|
||||
* [Mac](#mac)
|
||||
* [Math](#math)
|
||||
* [Mise](#mise)
|
||||
@@ -169,9 +170,11 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
|
||||
- [Allow Edits From The Start](claude-code/allow-edits-from-the-start.md)
|
||||
- [Ask An Agent To Fix Merge Conflicts](claude-code/ask-an-agent-to-fix-merge-conflicts.md)
|
||||
- [Build From My Phone In Cloud Environments](claude-code/build-from-my-phone-in-cloud-environments.md)
|
||||
- [Distinguish Sessions With Different Colors](claude-code/distinguish-sessions-with-different-colors.md)
|
||||
- [Monitor Usage Limits From CLI](claude-code/monitor-usage-limits-from-cli.md)
|
||||
- [Open Current Prompt In Default Editor](claude-code/open-current-prompt-in-default-editor.md)
|
||||
- [Pick Up Session Locally That Started In Cloud](claude-code/pick-up-session-locally-that-started-in-cloud.md)
|
||||
- [Resume Specific Session](claude-code/resume-specific-session.md)
|
||||
- [Set Permission Mode When Starting Session](claude-code/set-permission-mode-when-starting-session.md)
|
||||
- [Stash The Current Prompt To Send Another First](claude-code/stash-the-current-prompt-to-send-another-first.md)
|
||||
@@ -227,6 +230,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
- [Parameterized SCSS Mixins](css/parameterized-scss-mixins.md)
|
||||
- [Prevent Invisible Elements From Being Clicked](css/prevent-invisible-elements-from-being-clicked.md)
|
||||
- [:root Has Higher Specificity Than html](css/root-has-higher-specificity-than-html.md)
|
||||
- [Show Full URLs With Print Styles](css/show-full-urls-with-print-styles.md)
|
||||
- [Style A Background With A Linear Gradient](css/style-a-background-with-a-linear-gradient.md)
|
||||
- [Using Maps In SCSS](css/using-maps-in-scss.md)
|
||||
|
||||
@@ -479,11 +483,13 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
### GitHub
|
||||
|
||||
- [Access Your GitHub Profile Photo](github/access-your-github-profile-photo.md)
|
||||
- [Create A Private Repo From The CLI](github/create-a-private-repo-from-the-cli.md)
|
||||
- [Create And Push To New Repo From CLI](github/create-and-push-to-new-repo-from-cli.md)
|
||||
- [List PRs Awaiting Your Review](github/list-prs-awaiting-your-review.md)
|
||||
- [Open A PR To An Unforked Repo](github/open-a-pr-to-an-unforked-repo.md)
|
||||
- [Open File To Specific Line In Browser](github/open-file-to-specific-line-in-browser.md)
|
||||
- [Process JSON Output From gh With jq](github/process-json-output-from-gh-with-jq.md)
|
||||
- [Rerun Failed Jobs For Current Branch](github/rerun-failed-jobs-for-current-branch.md)
|
||||
- [Target Another Repo When Creating A PR](github/target-another-repo-when-creating-a-pr.md)
|
||||
- [Tell gh What The Default Repo Is](github/tell-gh-what-the-default-repo-is.md)
|
||||
|
||||
@@ -494,6 +500,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
- [Disable A Workflow With The gh CLI](github-actions/disable-a-workflow-with-the-gh-cli.md)
|
||||
- [Reference An Encrypted Secret In An Action](github-actions/reference-an-encrypted-secret-in-an-action.md)
|
||||
- [Run Schedule Action To Commit Regular Updates](github-actions/run-scheduled-action-to-commit-regular-updates.md)
|
||||
- [Set Repository Secret From CLI](github-actions/set-repository-secret-from-cli.md)
|
||||
- [Trigger A Workflow Via An API Call](github-actions/trigger-a-workflow-via-an-api-call.md)
|
||||
- [Use Labels To Block PR Merge](github-actions/use-labels-to-block-pr-merge.md)
|
||||
|
||||
@@ -748,6 +755,10 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
- [Translate To Canonical Tags With Small Model](llm/translate-to-canonical-tags-with-small-model.md)
|
||||
- [Use The llm CLI With Claude Models](llm/use-the-llm-cli-with-claude-models.md)
|
||||
|
||||
### Logseq
|
||||
|
||||
- [Access Daily Journal From CLI With HTTP Server](logseq/access-daily-journal-from-cli-with-http-server.md)
|
||||
|
||||
### Mac
|
||||
|
||||
- [Access All Screen And Video Capture Options](mac/access-all-screen-and-video-capture-options.md)
|
||||
@@ -1872,6 +1883,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
- [Make Neovim The Default Way To View Man Pages](unix/make-neovim-the-default-way-to-view-man-pages.md)
|
||||
- [Manually Pass Two Git Files To Delta](unix/manually-pass-two-git-files-to-delta.md)
|
||||
- [Map A Domain To localhost](unix/map-a-domain-to-localhost.md)
|
||||
- [Merge A Sequence Of Lines Of Output](unix/merge-a-sequence-of-lines-of-output.md)
|
||||
- [Move A List Of Files To Another Directory](unix/move-a-list-of-files-to-another-directory.md)
|
||||
- [Negative Look-Ahead Search With ripgrep](unix/negative-look-ahead-search-with-ripgrep.md)
|
||||
- [Occupy A Local Port With Netcat](unix/occupy-a-local-port-with-netcat.md)
|
||||
@@ -1892,6 +1904,7 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
- [Rename A Bunch Of Files By Constructing mv Commands](unix/rename-a-bunch-of-files-by-constructing-mv-commands.md)
|
||||
- [Repeat Yourself](unix/repeat-yourself.md)
|
||||
- [Replace Pattern Across Many Files In A Project](unix/replace-pattern-across-many-files-in-a-project.md)
|
||||
- [Restart Process Managed By `process-compose`](unix/restart-process-managed-by-process-compose.md)
|
||||
- [Restart Specific Overmind Process](unix/restart-specific-overmind-process.md)
|
||||
- [Reverse Each Line Of A File](unix/reverse-each-line-of-a-file.md)
|
||||
- [Run A Command Repeatedly Several Times](unix/run-a-command-repeatedly-several-times.md)
|
||||
@@ -2143,12 +2156,14 @@ If you've learned something here, support my efforts writing daily TILs by
|
||||
- [Change Window Name In iTerm](workflow/change-window-name-in-iterm.md)
|
||||
- [Configure Email Redirect With Cloudflare](workflow/configure-email-redirect-with-cloudflare.md)
|
||||
- [Control Media With Drop Keyboard](workflow/control-media-with-drop-keyboard.md)
|
||||
- [Create 1Password Login Item From The CLI](workflow/create-1password-login-item-from-the-cli.md)
|
||||
- [Convert An ePub Document To PDF On Mac](workflow/convert-an-epub-document-to-pdf-on-mac.md)
|
||||
- [Create A Local Sanity Dataset Backup](workflow/create-a-local-sanity-dataset-backup.md)
|
||||
- [Create A Public URL For A Local Server](workflow/create-a-public-url-for-a-local-server.md)
|
||||
- [Create Todo Items In Logseq](workflow/create-todo-items-in-logseq.md)
|
||||
- [Do Project Time Tracking From The CLI](workflow/do-project-time-tracking-from-the-cli.md)
|
||||
- [Enable Dev Tools For Safari](workflow/enable-dev-tools-for-safari.md)
|
||||
- [Ensure Tooltips Appear In Screenshots](workflow/ensure-tooltips-appear-in-screenshots.md)
|
||||
- [Forward Stripe Events To Local Server](workflow/forward-stripe-events-to-local-server.md)
|
||||
- [Get URL For GitHub User Profile Photo](workflow/get-url-for-github-user-profile-photo.md)
|
||||
- [Get Your Public IP Address](workflow/get-your-public-ip-address.md)
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# Build From My Phone In Cloud Environments
|
||||
|
||||
I mostly use Claude Code from a terminal with the `claude` CLI. Everything is
|
||||
running on my machine (except the inference). The codebase is already there, the
|
||||
feature branch is already in flight, all my tools and dotfiles are installed,
|
||||
the dev server or container VMs are running, etc. It's the closest to how I
|
||||
already worked before coding harnesses and allows me to seamlessly flow between
|
||||
agentic code, review, making my own edits, and so forth.
|
||||
|
||||
However, I've been finding it pretty satisfying to open _Claude Code_ either in
|
||||
the MacOS app or iOS app, connect a GitHub repo, and then ask for a quick
|
||||
feature landed as a PR.
|
||||
|
||||
This flow uses [Claude in the Cloud](https://code.claude.com/docs/en/claude-code-on-the-web) to boot up a
|
||||
development environment, pull down your codebase, create a branch, build a
|
||||
feature, run tests, boot the app, do all the different explorations and checks
|
||||
that `claude` typically does, and eventually land a PR back on GitHub.
|
||||
|
||||
What I find particularly remarkable about this flow is that this _cloud session_
|
||||
is effectively synced across any device where I'm using Claude. So while I'm on
|
||||
the train home from the gym, I open the Claude iOS app, pick my repo, and
|
||||
describe a feature. By the time I get home, I open Claude.app on my computer
|
||||
where I can skim through the chat summary, view the diff, and then suggest next
|
||||
steps or jump to the PR on GitHub.
|
||||
|
||||
I'm finding this workflow particularly exciting for side projects because I can
|
||||
kick off feature experiments from anywhere when the idea comes to me.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Pick Up Session Locally That Started In Cloud
|
||||
|
||||
I've been enjoying using _Claude Code_ from the iOS and MacOS apps for various
|
||||
side tasks recently. For smaller things I can usually get most of the way there
|
||||
from the app. And eventually I pull down the branch or have Claude create a PR
|
||||
that I can review.
|
||||
|
||||
Sometimes I want to transfer the session onto my computer to pick up where it
|
||||
left off for various reasons (e.g. I want the session to have access to some
|
||||
local data or specific dependencies).
|
||||
|
||||
The `claude` CLI has a flag for that — `--teleport`.
|
||||
|
||||
> Resume a teleport session, optionally specify session ID
|
||||
|
||||
```
|
||||
❯ claude --teleport
|
||||
|
||||
Select a session to resume (jbranchaud/still):
|
||||
|
||||
Updated Session Title
|
||||
❯ 1. 21m ago Blogmark link search modal
|
||||
2. 11h ago Mobile feed reader margins
|
||||
3. 11h ago Feed pagination with Pagy
|
||||
4. 1d ago RSS feed highlights and annotations
|
||||
5. 1d ago RSS feed categories
|
||||
6. 3d ago Blogmarks image drag-and-drop upload
|
||||
|
||||
↑/↓ to select · Enter to confirm · Esc to cancel
|
||||
```
|
||||
|
||||
This is similar to how `--resume` works, but it is for a session that was
|
||||
previously running in the cloud.
|
||||
@@ -0,0 +1,46 @@
|
||||
# Show Full URLs With Print Styles
|
||||
|
||||
Web pages are best experienced in a browser where you can fully interact with
|
||||
them. Links, for instance, can be hovered, inspected, and clicked on to navigate
|
||||
to the target location -- that's a core part of the web browser experience and
|
||||
what makes the internet.
|
||||
|
||||
Some people have printers though and they want to be able to print off web
|
||||
pages. Any web page can be printed off as is, but if your site or app is
|
||||
anticipating certain pages being printed, then you may add some
|
||||
`@print`-specific CSS styling to improve how it looks in print format.
|
||||
|
||||
Links are a prime example of lost interactivity. When printed, links render as
|
||||
blue underlined text with no way to know what they are linking to. One trick
|
||||
that I recently picked up from [this lobste.rs thread](https://lobste.rs/s/olnqh2/websites_should_be_printable#c_wigxfy) is to
|
||||
add _after content_ that renders the actual, full URL next to the link.
|
||||
|
||||
```css
|
||||
@media print
|
||||
{
|
||||
a[href]::after
|
||||
{
|
||||
content: " [" attr(href) "]";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This means that when a page has `<a href="https://still.visualmode.dev">still</a>`, the printed version will not
|
||||
just render the word "still", but will be styled to render `still [https://still.visualmode.dev]`.
|
||||
|
||||
This will add content after links for both absolute URLs and relative paths (and
|
||||
anchor tags). If I wanted to limit the after content to only show absolute URLs,
|
||||
I could add a bit more specificity to the matching tag.
|
||||
|
||||
```css
|
||||
@media print
|
||||
{
|
||||
a[href^="http"]::after
|
||||
{
|
||||
content: " [" attr(href) "]";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `^=` matches the pattern of `http` on the start of the `href` string which
|
||||
means it will only display absolute URLs.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Set Repository Secret From CLI
|
||||
|
||||
I set up a GitHub Action that will run daily and potentially push data up to a
|
||||
3rd-party API. To be able to post to that API, the action must include a secret
|
||||
as the bearer token in the requests. I need to securely include that secret in
|
||||
the GitHub Actions environment for this repo.
|
||||
|
||||
I can do that from the CLI with `gh` like so:
|
||||
|
||||
```bash
|
||||
❯ gh secret set TIL_SYNC_TOKEN
|
||||
? Paste your secret: ****************************************************************
|
||||
```
|
||||
|
||||
Notice that it prompts me for the secret and stars out what I paste in. That way
|
||||
the secret doesn't end up in my bash history and isn't visible on my screen.
|
||||
|
||||
After I've run this, I can see that the secret is set by opening up the repo in
|
||||
the GitHub web UI, clicking on _Settings_ > _Secrets and Variables_ > _Actions_.
|
||||
I should see `TIL_SYNC_TOKEN` listed under the _Repository Secrets_ section.
|
||||
|
||||
Here is an excerpt from my workflow action sync script where that secret is
|
||||
referenced -- notice the `${{ secrets.TIL_SYNC_TOKEN }}`.
|
||||
|
||||
```yaml
|
||||
- name: Sync posts
|
||||
env:
|
||||
TIL_SYNC_URL: ${{ vars.TIL_SYNC_URL }}
|
||||
TIL_SYNC_TOKEN: ${{ secrets.TIL_SYNC_TOKEN }}
|
||||
run: ruby script/til_sync/til_sync.rb --repo til ${{ inputs.all && '--all' || '--days 3' }}
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
# Create A Private Repo From The CLI
|
||||
|
||||
The vast majority of the GitHub repos that I've created over my career have been
|
||||
done from the web UI. It was only recently that I found out that [I can create a
|
||||
new repo from the CLI with `gh`](create-and-push-to-new-repo-from-cli.md).
|
||||
|
||||
A repo can be created for the current directory (where a local git repo already
|
||||
exists) using the `gh repo create` command. I'm wanting this to be a private
|
||||
repo so I can include the `--private` flag instead of the `--public` flag.
|
||||
|
||||
```bash
|
||||
❯ gh repo create marathon-training --private --source=. --remote=origin --push
|
||||
✓ Created repository jbranchaud/marathon-training on github.com
|
||||
https://github.com/jbranchaud/marathon-training
|
||||
✓ Added remote https://github.com/jbranchaud/marathon-training.git
|
||||
Enumerating objects: 125, done.
|
||||
Counting objects: 100% (125/125), done.
|
||||
Delta compression using up to 16 threads
|
||||
Compressing objects: 100% (114/114), done.
|
||||
Writing objects: 100% (125/125), 56.69 KiB | 14.17 MiB/s, done.
|
||||
Total 125 (delta 52), reused 0 (delta 0), pack-reused 0 (from 0)
|
||||
remote: Resolving deltas: 100% (52/52), done.
|
||||
To https://github.com/jbranchaud/marathon-training.git
|
||||
* [new branch] HEAD -> main
|
||||
branch 'main' set up to track 'origin/main' by rebasing.
|
||||
✓ Pushed commits to https://github.com/jbranchaud/marathon-training.git
|
||||
```
|
||||
|
||||
Since I am running this command from the root directory of the git-backed
|
||||
project, I specify the `--source` as `.` (mean _here_, the current directory).
|
||||
The remaining flags tell it what the remote should be set up as and that I want
|
||||
to push this local repo up to the GitHub remote once it is created.
|
||||
|
||||
See `gh repo create --help` for more details.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Rerun Failed Jobs For Current Branch
|
||||
|
||||
I have a branch that I've already opened a PR for. I've made more changes, run
|
||||
the tests, and pushed up the latest to the remote. I know the tests should have
|
||||
been green, but I'm seeing a flickering test fail in CI. I want to retrigger the
|
||||
relevant failed jobs to see if I can get the flickers to pass.
|
||||
|
||||
First, I need to figure out the workflow ID with any failed jobs.
|
||||
|
||||
```bash
|
||||
❯ gh run list --branch "$(git branch --show-current)" --status failure
|
||||
STATUS TITLE WORKFLOW BRANCH EVENT ID ELAPSED AGE
|
||||
X Better comp... Ruby on R... jbranchau... pull_request 38778306948 10m54s about 25 ...
|
||||
```
|
||||
|
||||
This one-liner does that by referencing the current branch (via `git`) and then
|
||||
asking `gh` to list failed workflows associated with that branch.
|
||||
|
||||
Grabbing the `ID` value, I can then ask `gh` to rerun failed jobs for that
|
||||
workflow.
|
||||
|
||||
```bash
|
||||
❯ gh run rerun 38778306948 --failed
|
||||
✓ Requested rerun (failed jobs) of run 38778306948
|
||||
```
|
||||
|
||||
Opening that PR up in the browser, I can see that the specific workflow has been
|
||||
rerun and is currently _in progress_.
|
||||
|
||||
See `gh run list --help` and `gh run rerun --help` for more details.
|
||||
@@ -0,0 +1,72 @@
|
||||
# Access Daily Journal From CLI With HTTP Server
|
||||
|
||||
I use [logseq](https://logseq.com/) as the daily driver for my notes both inside
|
||||
and outside of work. I like the organization provided by the outliner notetaking
|
||||
style.
|
||||
|
||||
I now want to set up some automations that interact with my notes. I originally
|
||||
figured this would involve reading directly from markdown files on disk.
|
||||
However, they recently migrated to a SQLite storage format and I learned that
|
||||
there is an HTTP server you can run for more reliable interactions.
|
||||
|
||||
The HTTP server needs to be enabled. To do this, I did the following (though I'm
|
||||
not sure if _Developer Mode_ is required):
|
||||
|
||||
1. Find the `...` icon to access the app's main menu
|
||||
2. Open _Settings_
|
||||
3. Enable _Developer Mode_ under _Advanced_
|
||||
4. Enable _HTTP API Server_ under _Features_
|
||||
5. Restart the logseq app
|
||||
6. Click the disabled _API_ icon that is in the upper-right next to the
|
||||
navigational arrows
|
||||
7. Create a new _Authorization Token_ and copy the value
|
||||
8. Click _Start Server_ and it will run at `http://127.0.0.1:12315`
|
||||
|
||||
With all that in place, the server is running and ready to accept my first
|
||||
query. I want to get a look at my notes so far today, so I'll run a `curl`
|
||||
request against the `/api` path with the auth token I copied.
|
||||
|
||||
```bash
|
||||
❯ curl -s -X POST http://127.0.0.1:12315/api \
|
||||
-H "Authorization: Bearer $LOGSEQ_API_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"method":"logseq.Editor.getPageBlocksTree","args":["Oct 31st, 2026"]}'
|
||||
[{"updatedAt":1793456696397,"createdAt":1793456670024,"parent":{"id":5943},"children":[],"id":5947,"level":1,"uuid":"6ae5fa1e-afa2-46c9-abbc-abf58b434e3e","fullTitle":"Working on setting up the HTTP server for logseq to see if I can interact with it via the CLI.","content":"Working on setting up the HTTP server for logseq to see if I can interact with it via the CLI.","order":"a0","title":"Working on setting up the HTTP server for logseq to see if I can interact with it via the CLI.","page":{"id":5943}},{"updatedAt":1793456702190,"createdAt":1793456697156,"parent":{"id":5943},"children":[{"updatedAt":1793456702212,"createdAt":1793456702212,"parent":{"id":5948},"children":[],"id":5949,"level":2,"uuid":"6ae5fa3e-0865-4713-9690-c456fb1a37ad","fullTitle":"","content":"","order":"a0","title":"","page":{"id":5943}}],"id":5948,"level":1,"uuid":"6ae5fa39-96bc-4f26-9d5f-2b3b3a366070","fullTitle":"[[6aa01dba-1b28-4540-b205-5254ee37d825]]","content":"[[6aa01dba-1b28-4540-b205-5254ee37d825]]","order":"a1","title":"[[6aa01dba-1b28-4540-b205-5254ee37d825]]","page":{"id":5943},"refs":[{"id":642}]}]%
|
||||
```
|
||||
|
||||
The data we pass as the request body includes the `method` we are running which
|
||||
is "get all the blocks for the specified page"
|
||||
([`getPageBlocksTree`](https://plugins-doc.logseq.com/logseq/Editor/getPageBlocksTree)).
|
||||
The `args` then specify what page we are referring to. In this case, today's
|
||||
daily journal -- `"Oct 31st, 2026"` (👻). The result is that pile of JSON.
|
||||
|
||||
Whenever I get a long line of JSON like that, I like to use `jq` at the very
|
||||
least to pretty-print it or even to dig in a bit.
|
||||
|
||||
```bash
|
||||
❯ curl -s -X POST http://127.0.0.1:12315/api \
|
||||
-H "Authorization: Bearer $LOGSEQ_API_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"method":"logseq.Editor.getPageBlocksTree","args":["Oct 31st, 2026"]}' | jq
|
||||
[
|
||||
{
|
||||
"updatedAt": 1793456696397,
|
||||
"createdAt": 1793456670024,
|
||||
"parent": {
|
||||
"id": 5943
|
||||
},
|
||||
"children": [],
|
||||
"id": 5947,
|
||||
"level": 1,
|
||||
"uuid": "6ae5fa1e-afa2-46c9-abbc-abf58b434e3e",
|
||||
"fullTitle": "Working on setting up the HTTP server for logseq to see if I can interact with it via the CLI.",
|
||||
"content": "Working on setting up the HTTP server for logseq to see if I can interact with it via the CLI.",
|
||||
"order": "a0",
|
||||
"title": "Working on setting up the HTTP server for logseq to see if I can interact with it via the CLI.",
|
||||
"page": {
|
||||
"id": 5943
|
||||
}
|
||||
},
|
||||
...
|
||||
]
|
||||
```
|
||||
@@ -0,0 +1,42 @@
|
||||
# Merge A Sequence Of Lines Of Output
|
||||
|
||||
More often than not when I'm chaining a sequence of Unix commands together, I'm
|
||||
eventually trying to fan them out or execute each argument separately. I
|
||||
recently had the need for a bunch of separate lines of output to be fanned back
|
||||
in to a single line.
|
||||
|
||||
The tool I found for this job is `paste` (not the most intuitive name).
|
||||
|
||||
> merge corresponding or subsequent lines of files
|
||||
|
||||
I was listing out all the categories that my active [TIL posts](https://github.com/jbranchaud/til) full under. I used the following
|
||||
command to do that.
|
||||
|
||||
```bash
|
||||
❯ git ls-files '*/*.md' | cut -d/ -f1 | sort -u
|
||||
ack
|
||||
ansible
|
||||
astro
|
||||
aws
|
||||
bash
|
||||
brew
|
||||
chrome
|
||||
...
|
||||
```
|
||||
|
||||
Those are all my categories, but then the format I really wanted was for them to
|
||||
be all on the same line with a clear delimiter so that I could paste them for
|
||||
[use in another script](/llm/translate-to-canonical-tags-with-small-model.md).
|
||||
|
||||
The trick is to tack on one more pipe to `paste`. The `-s` tells `paste` to join
|
||||
every line from a given input file (e.g. stdin) onto a single line. The `-d`
|
||||
allows for overriding the default delimiter (tab) with something like a `,`.
|
||||
Lastly, the trailing `-` tells `paste` to read from stdin rather than some other
|
||||
named file(s).
|
||||
|
||||
```bash
|
||||
❯ git ls-files '*/*.md' | cut -d/ -f1 | sort -u | paste -sd, -
|
||||
ack,ansible,astro,aws,bash,brew,chrome,claude-code,clojure,css,cursor,deno,devops,docker,drizzle,elixir,gatsby,git,github,github-actions,go,groq,heroku,html,http,inngest,internet,java,javascript,jj,jq,kitty,linux,llm,mac,math,mise,mongodb,mysql,neovim,netlify,next-auth,nextjs,phoenix,planetscale,pnpm,postgres,prisma,python,rails,react,react_native,react-testing-library,reason,remix,rspec,ruby,sed,shell,sqlite,streaming,tailwind,taskfile,tmux,typescript,unix,vercel,vim,vscode,webpack,workflow,xstate,yaml,zed,zod,zsh
|
||||
```
|
||||
|
||||
See `man paste` for more details.
|
||||
@@ -0,0 +1,28 @@
|
||||
# Restart Process Managed By `process-compose`
|
||||
|
||||
I'm working on a project where we are experimenting with
|
||||
[`process-compose`](https://github.com/F1bonacc1/process-compose) as a better
|
||||
way orchestrate a set of processes that all need to be running for a web
|
||||
development server (Rails) to work. This includes the Rails server itself, a
|
||||
JavaScript build process, PostgreSQL, a background worker process, etc.
|
||||
|
||||
In the past [I've used `overmind` with
|
||||
Procfiles](/rails/run-dev-processes-with-overmind-instead-of-foreman.md) to do a
|
||||
similar sort of thing. No matter what tooling is in play, from time to time, I
|
||||
will eventually need to restart one of the processes that has become stale.
|
||||
|
||||
The `vite` (JavaScript build) process is a good example of this. Configuration
|
||||
changes, new `npm` dependencies, and tailwind classes on new files can all lead
|
||||
to the build being stale.
|
||||
|
||||
From the `process-compose` TUI, I can navigate the cursor over the `vite`
|
||||
process and hit `Ctrl-r` to restart the process.
|
||||
|
||||
I can also issue a restart via the CLI like so:
|
||||
|
||||
```
|
||||
❯ mise exec -- process-compose process restart vite
|
||||
Process vite restarted
|
||||
```
|
||||
|
||||
[source](https://f1bonacc1.github.io/process-compose/cli/process-compose_process_restart/)
|
||||
@@ -0,0 +1,38 @@
|
||||
# Create 1Password Login Item From The CLI
|
||||
|
||||
The default shape of a login item in 1Password is _Username_ and _Password_.
|
||||
Whenever I'm trying to save something in 1Password, like an AWS Access Key for
|
||||
example, I find myself manually adjusting the fields to get it into the right
|
||||
shape for that item.
|
||||
|
||||
What I realized would be nicer is using [`op` (the 1Password
|
||||
CLI)](https://www.1password.dev/cli) to create a login item with the shape I
|
||||
want (which I can later reference in my shell history). Then I can pop open the
|
||||
desktop app and update the latest entry with the actually secret values that I
|
||||
copy from, in this case, the AWS Console.
|
||||
|
||||
```bash
|
||||
❯ op item create --vault "Personal" --category login --title "AWS - jbranchaud-lastword-cli" \
|
||||
'Access Key ID[text]=TODO' \
|
||||
'Secret Access Key[concealed]=TODO' \
|
||||
'Default region[text]=us-east-1'
|
||||
ID: abc123
|
||||
Title: AWS - jbranchaud-lastword-cli
|
||||
Vault: Personal (efg456)
|
||||
Created: now
|
||||
Updated: now
|
||||
Favorite: false
|
||||
Version: 1
|
||||
Category: LOGIN
|
||||
Fields:
|
||||
Access Key ID: TODO
|
||||
Secret Access Key: [use 'op item get abc123 --reveal' to reveal]
|
||||
Default region: us-east-1
|
||||
```
|
||||
|
||||
In this command I point to my `Personal` vault, I update the title of the login
|
||||
item inline, and then I have some custom fields on the item that match the shape
|
||||
of this scenario.
|
||||
|
||||
When I hit enter, a listing of fields is output. I can then hop over to the
|
||||
desktop app to set the actually ID and secret for the access key.
|
||||
@@ -0,0 +1,18 @@
|
||||
# Ensure Tooltips Appear In Screenshots
|
||||
|
||||
I use [CleanShot X](https://cleanshot.com/) for all my screenshot needs. It's by
|
||||
far the best tool for the job.
|
||||
|
||||
I'm a big proponent of taking high-context screenshots. That is, including
|
||||
everything in the screenshot that another person viewing it would need to know
|
||||
so that they don't have to answer follow up questions. This usually means other
|
||||
parts of the window besides the focal point or including the URL bar.
|
||||
|
||||
Another, less common, aspect of a shot I sometimes need, especially in a
|
||||
browser, are hover-based visual elements. That could be a tooltip or the option
|
||||
in a dropdown the cursor is over. Sometimes it is even a visual element that
|
||||
goes away after a beat.
|
||||
|
||||
To capture these with CleanShot X, I need to turn on the "Freeze screen when
|
||||
taking a screenshot" setting which can be found in _Settings_ under the
|
||||
_Screenshots_ tab in the _Capture_ section.
|
||||
Reference in New Issue
Block a user