mirror of
https://github.com/cole-maxwell1/dotfiles.git
synced 2026-10-27 16:32:49 -05:00
Compare commits
10
Commits
3fbf0ea3c8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d4ba3e291 | ||
|
|
12a524a6c8 | ||
|
|
3b797f3be1 | ||
|
|
3a05a40cfd | ||
|
|
6c7604b218 | ||
|
|
2c4e6dbf95 | ||
|
|
8e91bb9945 | ||
|
|
dfbb071b35 | ||
|
|
a4fc747df2 | ||
|
|
71f73fccbc |
@@ -27,4 +27,8 @@ Strictly adhere to the following Conventional Commit specification rules:
|
|||||||
- `ops`: Infrastructure, CI/CD pipelines, deployment, or operational scripts.
|
- `ops`: Infrastructure, CI/CD pipelines, deployment, or operational scripts.
|
||||||
- `chore`: Maintenance tasks (e.g., updating `.gitignore`, repo setup).
|
- `chore`: Maintenance tasks (e.g., updating `.gitignore`, repo setup).
|
||||||
|
|
||||||
|
### Message Body
|
||||||
|
|
||||||
|
The message body should provide a detailed description of the changes, including any relevant context or reasoning.
|
||||||
|
|
||||||
Provide ONLY the proposed commit message inside a raw code block, followed by a request for my approval.
|
Provide ONLY the proposed commit message inside a raw code block, followed by a request for my approval.
|
||||||
|
|||||||
@@ -24,12 +24,15 @@
|
|||||||
"which *": "allow",
|
"which *": "allow",
|
||||||
"ls *": "allow",
|
"ls *": "allow",
|
||||||
"wc *": "allow",
|
"wc *": "allow",
|
||||||
|
"head *": "allow",
|
||||||
|
"tail *": "allow",
|
||||||
// Go
|
// Go
|
||||||
"go build *": "allow",
|
"go build *": "allow",
|
||||||
"go test *": "allow",
|
"go test *": "allow",
|
||||||
"go vet *": "allow",
|
"go vet *": "allow",
|
||||||
"go mod tidy": "allow",
|
"go mod tidy": "allow",
|
||||||
"go mod download": "allow",
|
"go mod download": "allow",
|
||||||
|
"gofmt *": "allow",
|
||||||
// Node.js
|
// Node.js
|
||||||
"npm ci": "allow",
|
"npm ci": "allow",
|
||||||
"npm test": "allow",
|
"npm test": "allow",
|
||||||
@@ -40,6 +43,12 @@
|
|||||||
"npm ls *": "allow",
|
"npm ls *": "allow",
|
||||||
"npm outdated": "allow",
|
"npm outdated": "allow",
|
||||||
"npm audit *": "allow",
|
"npm audit *": "allow",
|
||||||
|
"npm run test:unit": "allow",
|
||||||
|
"npm run test:integration": "allow",
|
||||||
|
"npm run test:e2e": "allow",
|
||||||
|
"npm run type-check": "allow",
|
||||||
|
"npm run package:dev": "allow",
|
||||||
|
"npx vitest run *": "allow",
|
||||||
"npx *": "ask",
|
"npx *": "ask",
|
||||||
// Python
|
// Python
|
||||||
"python -m unittest *": "allow",
|
"python -m unittest *": "allow",
|
||||||
@@ -64,6 +73,17 @@
|
|||||||
"docker ps *": "allow",
|
"docker ps *": "allow",
|
||||||
"docker logs *": "allow",
|
"docker logs *": "allow",
|
||||||
"docker compose logs *": "allow",
|
"docker compose logs *": "allow",
|
||||||
|
"docker manifest inspect": "allow",
|
||||||
|
// Ansible
|
||||||
|
"ansible-playbook --version": "allow",
|
||||||
|
"ansible-playbook --syntax-check *": "allow",
|
||||||
|
"ansible-lint --version": "allow",
|
||||||
|
// OpenTofu
|
||||||
|
"tofu version": "allow",
|
||||||
|
"tofu init -backend=false": "allow",
|
||||||
|
"tofu validate *": "allow",
|
||||||
|
"tofu fmt -check *": "allow",
|
||||||
|
"tofu plan *": "allow",
|
||||||
},
|
},
|
||||||
"read": {
|
"read": {
|
||||||
"/tmp/opencode": "allow",
|
"/tmp/opencode": "allow",
|
||||||
@@ -122,6 +142,10 @@
|
|||||||
"question": "allow",
|
"question": "allow",
|
||||||
"lsp": "allow",
|
"lsp": "allow",
|
||||||
"websearch": "allow",
|
"websearch": "allow",
|
||||||
|
"webfetch": "allow",
|
||||||
|
"task": "allow",
|
||||||
|
"todowrite": "allow",
|
||||||
|
"skill": "allow",
|
||||||
},
|
},
|
||||||
"mcp": {
|
"mcp": {
|
||||||
"zai-mcp-server": {
|
"zai-mcp-server": {
|
||||||
@@ -155,13 +179,19 @@
|
|||||||
},
|
},
|
||||||
"playwright": {
|
"playwright": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
|
"enabled": false,
|
||||||
"command": ["npx", "@playwright/mcp@latest"],
|
"command": ["npx", "@playwright/mcp@latest"],
|
||||||
"enabled": true,
|
|
||||||
},
|
},
|
||||||
"chrome-devtools": {
|
"chrome-devtools": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
|
"enabled": false,
|
||||||
"command": ["npx", "-y", "chrome-devtools-mcp@latest"],
|
"command": ["npx", "-y", "chrome-devtools-mcp@latest"],
|
||||||
},
|
},
|
||||||
|
"primevue": {
|
||||||
|
"type": "local",
|
||||||
|
"enabled": true,
|
||||||
|
"command": ["npx", "-y", "@primevue/mcp"],
|
||||||
|
},
|
||||||
"ibmi-server": {
|
"ibmi-server": {
|
||||||
"type": "local",
|
"type": "local",
|
||||||
"command": [
|
"command": [
|
||||||
@@ -194,11 +224,11 @@
|
|||||||
},
|
},
|
||||||
"lsp": true,
|
"lsp": true,
|
||||||
"formatter": true,
|
"formatter": true,
|
||||||
"model": "zai-coding-plan/glm-5.2",
|
"model": "openai/gpt-5.6-sol",
|
||||||
"small_model": "zai-coding-plan/glm-4.5-air",
|
"small_model": "openai/gpt-5.6-luna",
|
||||||
"agent": {
|
"agent": {
|
||||||
"explore": {
|
"explore": {
|
||||||
"model": "zai-coding-plan/glm-4.5-air",
|
"model": "openai/gpt-5.6-luna",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"share": "disabled",
|
"share": "disabled",
|
||||||
@@ -206,5 +236,9 @@
|
|||||||
"plugin": ["./plugins/ibmi-gate.ts", "@slkiser/opencode-quota@latest"],
|
"plugin": ["./plugins/ibmi-gate.ts", "@slkiser/opencode-quota@latest"],
|
||||||
"provider": {
|
"provider": {
|
||||||
"zai": {},
|
"zai": {},
|
||||||
|
"openai": {},
|
||||||
|
},
|
||||||
|
"experimental": {
|
||||||
|
"disable_paste_summary": true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
name: bash
|
||||||
|
description: Shell scripting conventions (set -euo pipefail, quoting, shellcheck). Use when editing .sh or .bash files.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Bash Conventions
|
||||||
|
|
||||||
|
## Robustness
|
||||||
|
- Begin scripts with `#!/usr/bin/env bash` and `set -euo pipefail`.
|
||||||
|
- Pass `shellcheck` cleanly; treat its warnings as bugs.
|
||||||
|
|
||||||
|
## Quoting and expansion
|
||||||
|
- Double-quote all variable expansions (`"$var"`, `"${array[@]}"`).
|
||||||
|
- Prefer `[[ ]]` over `[ ]`; use arrays for argument lists rather than space-separated strings.
|
||||||
|
- Avoid `eval`; do not parse `ls` output.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
- Declare function-local variables with `local`.
|
||||||
|
- Use `trap` to clean up temporary files and directories.
|
||||||
|
- Use `printf` over `echo` for predictable output.
|
||||||
|
- Prefer a `$TMPDIR`-based path over hardcoded `/tmp` literals.
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: csharp
|
||||||
|
description: C# and .NET coding conventions. Use when reading, writing, or reviewing .cs, .razor, .csproj, or .sln files, or any .NET (C#) code.
|
||||||
|
---
|
||||||
|
|
||||||
|
# C# / .NET Conventions
|
||||||
|
|
||||||
|
Follow the Microsoft [Common C# code conventions](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/coding-style/coding-conventions) and [.NET naming guidelines](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/naming-guidelines). Match patterns already established in the target codebase.
|
||||||
|
|
||||||
|
## Structure
|
||||||
|
- Use file-scoped namespaces (`namespace Example.Services;`).
|
||||||
|
- Nullable reference types are enabled solution-wide; do not suppress warnings without cause.
|
||||||
|
- Use `record` types for DTOs and data carriers.
|
||||||
|
- Use `required` / `init`-only properties for immutable domain models.
|
||||||
|
- Use primary constructors for services and repositories that take injected dependencies.
|
||||||
|
- Mark classes `sealed` by default unless inheritance is intended.
|
||||||
|
- Prefix interfaces with `I` (`IRenderer`, `IRepository`).
|
||||||
|
|
||||||
|
## Expressions
|
||||||
|
- Use raw string literals (`""" ... """`) for multi-line SQL.
|
||||||
|
- Use `[GeneratedRegex]` partial methods for regex.
|
||||||
|
- Use collection expressions (`[]`, `[a, b]`).
|
||||||
|
|
||||||
|
## Async and cancellation
|
||||||
|
- Every async method takes `CancellationToken ct = default` and honors it cooperatively (`ct.ThrowIfCancellationRequested()` in long loops).
|
||||||
|
- Never drop the token when calling downstream async APIs.
|
||||||
|
|
||||||
|
## Logging
|
||||||
|
- Inject `ILogger<T>` and use structured logging with named parameters:
|
||||||
|
`_logger.LogInformation("Generated {Count} transactions", count);`
|
||||||
|
|
||||||
|
## Naming
|
||||||
|
- `PascalCase` for types and members.
|
||||||
|
- `_camelCase` for private fields.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
- Use xUnit. Mirror the source structure under a `Tests/` directory with a `Tests` suffix on file names.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
name: go
|
||||||
|
description: Idiomatic Go conventions. Use when editing .go files or go.mod/go.sum.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Go Conventions
|
||||||
|
|
||||||
|
Write strictly idiomatic Go following standard formatting and best practices.
|
||||||
|
|
||||||
|
## Formatting and style
|
||||||
|
- `gofmt` / `goimports` formatting is mandatory.
|
||||||
|
- Follow [Effective Go](https://go.dev/doc/effective_go) and the [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments).
|
||||||
|
|
||||||
|
## Design
|
||||||
|
- Accept `context.Context` as the first parameter on functions doing I/O or long work; honor cancellation.
|
||||||
|
- Compose via small interfaces; accept interfaces, return structs.
|
||||||
|
- Wire dependencies explicitly via constructor injection; avoid package-level mutable globals and DI frameworks.
|
||||||
|
- Return errors explicitly; wrap with `%w` (`fmt.Errorf("do thing: %w", err)`); classify with `errors.Is` / `errors.As`; never discard errors.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
- Write table-driven tests in `_test.go` using the standard `testing` package.
|
||||||
|
- Use `t.Run` for subtests; report failures with `t.Errorf` / `t.Fatalf`.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
name: htmx
|
||||||
|
description: HTMX v2 progressive-enhancement and hypermedia patterns.
|
||||||
|
---
|
||||||
|
|
||||||
|
# HTMX Conventions
|
||||||
|
|
||||||
|
Follow [HTMX](https://htmx.org) v2 and [Hypermedia Systems](https://hypermedia.systems/book/contents/) best practices.
|
||||||
|
|
||||||
|
## Philosophy
|
||||||
|
- Treat the server as the source of truth; return HTML fragments, not JSON, for hypermedia interactions.
|
||||||
|
- Prefer `hx-*` attributes over client-side JavaScript; reach for client JavaScript only when htmx cannot express the interaction.
|
||||||
|
- Build progressively: ensure pages function without JavaScript, then enhance with htmx.
|
||||||
|
|
||||||
|
## Patterns
|
||||||
|
- Target fragments with `hx-target` and swap with `hx-swap` (prefer `outerHTML` or `innerHTML` as appropriate).
|
||||||
|
- Return partial templates or fragments from endpoints; treat partials as isolated components that receive data via the page model.
|
||||||
|
- Use Out-of-Band Swaps (`hx-swap-oob`) to update multiple regions from a single response.
|
||||||
|
- Handle errors with a 4xx/5xx partial or `hx-on::responseError`.
|
||||||
|
|
||||||
|
## Keep clean
|
||||||
|
- Return semantic HTML from endpoints; avoid mixing `hx-*` attributes with conflicting client-side handlers.
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
name: primevue
|
||||||
|
description: PrimeVue v4 component patterns and Tailwind integration. Use when writing or styling PrimeVue components.
|
||||||
|
---
|
||||||
|
|
||||||
|
# PrimeVue v4 Conventions
|
||||||
|
|
||||||
|
Assume PrimeVue v4 is installed when answering Vue questions. Use the Composition API with `<script setup>`.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
- Register components via the PrimeVue plugin or import per component.
|
||||||
|
- Prefer official presets and theming over hand-rolled overrides.
|
||||||
|
|
||||||
|
## Tailwind integration
|
||||||
|
- TailwindCSS is available; when needed, apply utility classes through the component passthrough (`pt`) or the unstyled/preset mechanism rather than overriding internal DOM.
|
||||||
|
- Keep utility usage consistent with the project's styling layer.
|
||||||
|
|
||||||
|
## API detail
|
||||||
|
- For component props, events, slots, and passthrough (`pt`) keys, fetch the PrimeVue LLM docs index on demand: `https://v4.primevue.org/llms/llms.txt`. Follow the relevant component link for the exact signature.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: python
|
||||||
|
description: Python conventions (PEP 8, ruff, type hints). Use when editing .py files.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Python Conventions
|
||||||
|
|
||||||
|
## Style
|
||||||
|
- Follow PEP 8; run `ruff check` and `ruff format` for linting and formatting.
|
||||||
|
- Let ruff manage line length and import ordering; do not hand-format against it.
|
||||||
|
|
||||||
|
## Typing
|
||||||
|
- Add type hints on all function signatures; prefer modern syntax (`list[int]`, `X | None`) on supported Python versions.
|
||||||
|
- Use `dataclasses` (or Pydantic where validation is required) for structured data.
|
||||||
|
- Prefer an explicit exception hierarchy over bare `except:`.
|
||||||
|
|
||||||
|
## Idioms
|
||||||
|
- Prefer `pathlib.Path` over `os.path`.
|
||||||
|
- Use f-strings for interpolation; use the `logging` module with structured handlers instead of `print` in libraries.
|
||||||
|
- Prefer comprehensions and generator expressions over manual loops where readability is preserved.
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
- Use `unittest` (or `pytest` if the project adopts it); mirror the source layout under a `tests/` directory.
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
name: typescript
|
||||||
|
description: TypeScript conventions (Google style, strict mode, no any). Use when editing .ts or .tsx files, or tsconfig/jsconfig files.
|
||||||
|
---
|
||||||
|
|
||||||
|
# TypeScript Conventions
|
||||||
|
|
||||||
|
Follow the [Google TypeScript Style Guide](https://google.github.io/styleguide/tsguide.html).
|
||||||
|
|
||||||
|
## Typing
|
||||||
|
- `strict: true` in tsconfig; no implicit or explicit `any`.
|
||||||
|
- Strictly type all variables, functions, and interfaces.
|
||||||
|
- Prefer `unknown` over `any` when the type is genuinely unknown, then narrow.
|
||||||
|
- Prefer discriminated unions and type narrowing over runtime checks.
|
||||||
|
- Declare explicit return types on public and shared APIs.
|
||||||
|
|
||||||
|
## Style
|
||||||
|
- Prefer `interface` for object shapes; use `type` for unions and mapped types.
|
||||||
|
- Use `const` by default; `let` only when reassignment is required; never `var`.
|
||||||
|
- Prefer async/await over raw `.then`/`.catch` chains.
|
||||||
|
|
||||||
|
## Project overrides
|
||||||
|
A project's tsconfig or eslint config may relax rules (for example, disable `@typescript-eslint/no-explicit-any`); project configuration overrides these defaults.
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
name: vue
|
||||||
|
description: Vue 3 (Composition API, script setup, Pinia, Vue Router) conventions. Use when editing .vue files.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Vue 3 Conventions
|
||||||
|
|
||||||
|
Use Vue 3 with the Composition API exclusively.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
- Use `<script setup lang="ts">`; avoid the Options API.
|
||||||
|
- Type props with `defineProps<T>()` and emits with `defineEmits<T>()`.
|
||||||
|
- Keep components focused and small; organize by feature directory.
|
||||||
|
|
||||||
|
## State and routing
|
||||||
|
- Use Pinia setup stores (`defineStore('name', () => { ... })`) for shared state.
|
||||||
|
- Cancel superseded fetches with `AbortController`; expose loading and error state from stores.
|
||||||
|
- Use Vue Router with route guards for protected views.
|
||||||
|
|
||||||
|
## Reactivity
|
||||||
|
- Prefer `ref` / `reactive` and `computed` over manual watchers.
|
||||||
|
- Clean up side effects (timers, listeners, observers) in `onScopeDispose` or `onUnmounted`.
|
||||||
|
|
||||||
|
## API detail
|
||||||
|
- For exact reactivity, built-in component, and compiler behavior, fetch the Vue LLM docs index on demand: `https://vuejs.org/llms.txt`. Follow the relevant guide link for the specific API.
|
||||||
Executable
+135
@@ -0,0 +1,135 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# iso2usb-macos.sh - Write an ISO image to a USB drive on macOS.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./iso2usb-macos.sh [--prompt|-p] /path/to/input.iso
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
# -p, --prompt Skip El Torito auto-detection and go straight to the
|
||||||
|
# direct-write Y/N prompt with no pre-selected default.
|
||||||
|
#
|
||||||
|
# Requires: hdiutil, diskutil, dd (all built into macOS). Must be run with
|
||||||
|
# sudo privileges for the dd step (the script will prompt when needed).
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SKIP_DETECT=0
|
||||||
|
ISO_PATH=""
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
-p|--prompt)
|
||||||
|
SKIP_DETECT=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
echo "Usage: $0 [--prompt|-p] /path/to/input.iso"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
ISO_PATH="$1"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$ISO_PATH" ]]; then
|
||||||
|
echo "Usage: $0 [--prompt|-p] /path/to/input.iso"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ! -f "$ISO_PATH" ]]; then
|
||||||
|
echo "Error: file not found: $ISO_PATH"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# List external/removable disks only, to reduce risk of selecting an internal drive.
|
||||||
|
echo "Available external disks:"
|
||||||
|
echo "--------------------------"
|
||||||
|
diskutil list external
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -rp "Enter the disk identifier to write to (e.g. disk4): " DISK_ID
|
||||||
|
|
||||||
|
# Normalize input in case user includes /dev/ prefix.
|
||||||
|
DISK_ID="${DISK_ID#/dev/}"
|
||||||
|
DISK_PATH="/dev/${DISK_ID}"
|
||||||
|
RDISK_PATH="/dev/r${DISK_ID}"
|
||||||
|
|
||||||
|
if [[ ! -e "$DISK_PATH" ]]; then
|
||||||
|
echo "Error: $DISK_PATH does not exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DISK_INFO="$(diskutil info "$DISK_PATH")"
|
||||||
|
DISK_SIZE="$(echo "$DISK_INFO" | grep "Disk Size" | sed -E 's/.*Disk Size:[[:space:]]*//; s/[[:space:]]*\(.*//')"
|
||||||
|
# Not all diskutil info output includes a "Disk Size" field (varies by
|
||||||
|
# identifier type, e.g. whole-disk vs partition). Fall back to "Total Size"
|
||||||
|
# if the first lookup came back empty.
|
||||||
|
[[ -z "$DISK_SIZE" ]] && DISK_SIZE="$(echo "$DISK_INFO" | grep "Total Size" | sed -E 's/.*Total Size:[[:space:]]*//; s/[[:space:]]*\(.*//')"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Selected device: $DISK_PATH (${DISK_SIZE:-unknown size})"
|
||||||
|
echo "$DISK_INFO" | grep -E "Device / Media Name|Protocol|Total Size|Removable Media"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "WARNING: all data on $DISK_PATH will be destroyed."
|
||||||
|
read -rp "Type the disk identifier again to confirm (e.g. disk4): " CONFIRM_ID
|
||||||
|
if [[ "$CONFIRM_ID" != "$DISK_ID" ]]; then
|
||||||
|
echo "Confirmation did not match. Aborting."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
WORKDIR="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$WORKDIR"' EXIT
|
||||||
|
|
||||||
|
IMG_PATH=""
|
||||||
|
|
||||||
|
# Check for an El Torito boot record to determine if the ISO is hybrid.
|
||||||
|
# The boot record volume descriptor lives at sector 17 (byte offset 0x8800).
|
||||||
|
# Byte 0 of that sector is 0x00 (boot record type), followed by the string
|
||||||
|
# "CD001", followed by the boot system identifier. Hybrid/El Torito ISOs
|
||||||
|
# carry "EL TORITO SPECIFICATION" in that identifier field.
|
||||||
|
is_hybrid_iso() {
|
||||||
|
local iso="$1"
|
||||||
|
dd if="$iso" bs=1 skip=34823 count=23 2>/dev/null | grep -aq "EL TORITO SPECIFICATION"
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULT_DIRECT=""
|
||||||
|
if [[ "$SKIP_DETECT" -eq 1 ]]; then
|
||||||
|
echo "Skipping El Torito auto-detection (--prompt set)."
|
||||||
|
else
|
||||||
|
echo "Inspecting ISO for El Torito hybrid boot support..."
|
||||||
|
if is_hybrid_iso "$ISO_PATH"; then
|
||||||
|
echo "Detected: hybrid El Torito/ISO9660 image. Direct dd write should work."
|
||||||
|
DEFAULT_DIRECT="Y"
|
||||||
|
else
|
||||||
|
echo "No El Torito boot record found. This ISO is likely not hybrid;"
|
||||||
|
echo "converting via hdiutil is recommended."
|
||||||
|
DEFAULT_DIRECT="N"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
read -rp "Attempt direct write of the raw ISO without conversion? [${DEFAULT_DIRECT:-y/N}]: " DIRECT
|
||||||
|
DIRECT="${DIRECT:-$DEFAULT_DIRECT}"
|
||||||
|
if [[ "$DIRECT" =~ ^[Yy]$ ]]; then
|
||||||
|
IMG_PATH="$ISO_PATH"
|
||||||
|
else
|
||||||
|
echo "Converting ISO to UDRW image..."
|
||||||
|
hdiutil convert -format UDRW -o "${WORKDIR}/output.img" "$ISO_PATH"
|
||||||
|
# hdiutil appends .dmg to the output filename even though it is raw content.
|
||||||
|
IMG_PATH="${WORKDIR}/output.img.dmg"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Unmounting $DISK_PATH..."
|
||||||
|
diskutil unmountDisk "$DISK_PATH"
|
||||||
|
|
||||||
|
echo "Writing image to $RDISK_PATH. This may take several minutes..."
|
||||||
|
sudo dd if="$IMG_PATH" of="$RDISK_PATH" bs=1m status=progress
|
||||||
|
|
||||||
|
echo "Ejecting $DISK_PATH..."
|
||||||
|
diskutil eject "$DISK_PATH"
|
||||||
|
|
||||||
|
echo "Done."
|
||||||
@@ -21,11 +21,11 @@ fi
|
|||||||
|
|
||||||
# Add .local/bin to $PATH if it doesn't exist
|
# Add .local/bin to $PATH if it doesn't exist
|
||||||
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
if [[ ":$PATH:" != *":$HOME/.local/bin:"* ]]; then
|
||||||
export PATH=$PATH:$HOME/.local/bin
|
export PATH=$PATH:$HOME/.local/bin
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add script binaries to $PATH if they exist
|
# Add script binaries to $PATH if they exist
|
||||||
if [[ -d $HOME/.scripts && ":$PATH:" != *":$PATH:"* ]]; then
|
if [[ -d $HOME/.scripts && ":$PATH:" != *":$HOME/.scripts:"* ]]; then
|
||||||
export PATH=$PATH:$HOME/.scripts
|
export PATH=$PATH:$HOME/.scripts
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -53,6 +53,14 @@ if [[ "$(uname -s)" == "Darwin" ]]; then
|
|||||||
if [[ -d $HOME/Library/Python/3.8/bin && ":$PATH:" != *":$HOME/Library/Python/3.8/bin:"* ]]; then
|
if [[ -d $HOME/Library/Python/3.8/bin && ":$PATH:" != *":$HOME/Library/Python/3.8/bin:"* ]]; then
|
||||||
export PATH=$PATH:$HOME/Library/Python/3.8/bin
|
export PATH=$PATH:$HOME/Library/Python/3.8/bin
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Bitwarden SSH agent (only if the application is installed and the socket file exists)
|
||||||
|
local bw_app="/Applications/Bitwarden.app"
|
||||||
|
local bw_sock="$HOME/.bitwarden-ssh-agent.sock"
|
||||||
|
|
||||||
|
if [[ -d "$bw_app" && -S "$bw_sock" ]]; then
|
||||||
|
export SSH_AUTH_SOCK="$bw_sock"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Add goland $PATH if installed and not already in $PATH
|
# Add goland $PATH if installed and not already in $PATH
|
||||||
@@ -171,7 +179,7 @@ if command -v lsd &> /dev/null; then
|
|||||||
alias lg="lsd -F --group-dirs=first" # Group directories first
|
alias lg="lsd -F --group-dirs=first" # Group directories first
|
||||||
alias lt="lsd --tree --depth 5" # Show directory tree with depth of 5
|
alias lt="lsd --tree --depth 5" # Show directory tree with depth of 5
|
||||||
alias li="lsd -ilAF" # Show inode numbers
|
alias li="lsd -ilAF" # Show inode numbers
|
||||||
else
|
else
|
||||||
alias la="ls -a" # Show all files
|
alias la="ls -a" # Show all files
|
||||||
alias ll="ls -alh" # Show all files, long format, human readable sizes
|
alias ll="ls -alh" # Show all files, long format, human readable sizes
|
||||||
alias li="ls -ialh" # Show all files, long format, human readable sizes, inode numbers
|
alias li="ls -ialh" # Show all files, long format, human readable sizes, inode numbers
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ The zsh theme and plugins are installed manually rather than through a plugin ma
|
|||||||
├── .zshrc # zsh config: PATH, history, completions, prompt, aliases
|
├── .zshrc # zsh config: PATH, history, completions, prompt, aliases
|
||||||
├── .config/
|
├── .config/
|
||||||
│ ├── nvim/ # Neovim config (init.lua, lua/, after/, queries/)
|
│ ├── nvim/ # Neovim config (init.lua, lua/, after/, queries/)
|
||||||
│ └── opencode/ # opencode config (commands, plugins, MCP tools, rules)
|
│ └── opencode/ # opencode config (commands, plugins, skills, MCP tools, rules)
|
||||||
└── .scripts/ # Standalone shell scripts (on $PATH)
|
└── .scripts/ # Standalone shell scripts (on $PATH)
|
||||||
└── hello.sh
|
└── hello.sh
|
||||||
```
|
```
|
||||||
@@ -68,6 +68,29 @@ cd ~/dotfiles && stow -D .
|
|||||||
|
|
||||||
Running `stow .` again re-creates them.
|
Running `stow .` again re-creates them.
|
||||||
|
|
||||||
|
## Add new files or directories
|
||||||
|
|
||||||
|
Add each item to the repository at the same path it should have under the home directory. For example, opencode skills belong under `~/dotfiles/.config/opencode/skills/`. Then refresh the links:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd ~/dotfiles
|
||||||
|
stow .
|
||||||
|
```
|
||||||
|
|
||||||
|
If the corresponding target does not exist, Stow creates the symlink. This applies to an entire new directory such as `skills` and to files added inside an already-stowed directory.
|
||||||
|
|
||||||
|
If Stow reports that an existing target is neither a link nor a directory, the target is a real file that Stow will not overwrite. When the repository copy is authoritative, back up the target and rerun Stow:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mv ~/.config/opencode/opencode.jsonc ~/.config/opencode/opencode.jsonc.pre-stow-backup
|
||||||
|
cd ~/dotfiles
|
||||||
|
stow .
|
||||||
|
```
|
||||||
|
|
||||||
|
Repeat the backup step for every conflicting target listed by Stow. Review and remove backups only after confirming the linked configuration works.
|
||||||
|
|
||||||
|
Do not use `stow --adopt` for this workflow. `--adopt` copies the existing target into the repository, replacing the repository version, which is the opposite of making the repository authoritative.
|
||||||
|
|
||||||
## Secrets
|
## Secrets
|
||||||
|
|
||||||
If `~/.secrets` exists, `.zshrc` sources it near the top of the file so environment variables (API keys, tokens, etc.) are exported into the shell. This file is intentionally **not** part of the repo — create it locally and keep it out of version control.
|
If `~/.secrets` exists, `.zshrc` sources it near the top of the file so environment variables (API keys, tokens, etc.) are exported into the shell. This file is intentionally **not** part of the repo — create it locally and keep it out of version control.
|
||||||
|
|||||||
Reference in New Issue
Block a user