Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
8a51570
feat(scripts): add devc-remote.sh skeleton with logging and stubs
gerchowl Feb 22, 2026
1c5ac06
test(bats): add devc-remote script structure and parse_args tests
gerchowl Feb 22, 2026
35ed620
test(devc_remote_uri): add hex_encode unit tests
gerchowl Feb 22, 2026
46c7ba2
feat(devc_remote_uri): implement hex_encode
gerchowl Feb 22, 2026
73c4fad
feat(scripts): implement parse_args in devc-remote.sh
gerchowl Feb 22, 2026
d9d9f81
test(devc_remote_uri): add build_uri unit tests
gerchowl Feb 22, 2026
13ec6eb
feat(devc_remote_uri): implement build_uri
gerchowl Feb 22, 2026
19b2e51
feat(scripts): implement detect_editor_cli in devc-remote.sh
gerchowl Feb 22, 2026
d9496e8
test(devc_remote_uri): add CLI tests
gerchowl Feb 22, 2026
d6678b0
feat(scripts): implement check_ssh in devc-remote.sh
gerchowl Feb 22, 2026
45d8be3
feat(devc_remote_uri): implement CLI with argparse
gerchowl Feb 22, 2026
63a2099
feat(scripts): implement remote_preflight in devc-remote.sh
gerchowl Feb 22, 2026
07330eb
docs: add CHANGELOG entry for devc_remote_uri
gerchowl Feb 22, 2026
a31e038
feat(scripts): implement remote_compose_up, open_editor, and Python U…
gerchowl Feb 22, 2026
c185f78
feat(scripts): devc-remote.sh — bash orchestrator for remote devconta…
gerchowl Feb 22, 2026
8b6d88c
fix: resolve merge conflicts with feature/70-remote-devc-orchestration
gerchowl Feb 23, 2026
d863bf3
feat(scripts): devc_remote_uri.py — Cursor URI construction for remot…
gerchowl Feb 23, 2026
f7f1070
fix(scripts): correct devc-remote.sh URI construction and add justfil…
gerchowl Feb 23, 2026
9283a83
Merge branch 'dev' into feature/70-remote-devc-orchestration
gerchowl Feb 24, 2026
f23b281
refactor(scripts): use SSH-style path format for devc-remote
gerchowl Feb 24, 2026
79297b5
fix(scripts): default remote path to ~ instead of $HOME
gerchowl Feb 24, 2026
9a4b1cc
fix(ci): include devc_remote_uri tests in project checks coverage
gerchowl Feb 24, 2026
a8dfe87
Merge branch 'dev' into feature/70-remote-devc-orchestration
gerchowl Feb 24, 2026
1e955c9
test: add red test for bandit installation
gerchowl Feb 24, 2026
cf92da8
fix: install bandit system-wide in container image
gerchowl Feb 24, 2026
58f8813
fix: deploy check-skill-names.sh to workspace template
gerchowl Feb 24, 2026
4afbab9
docs: add CHANGELOG entry for #186
gerchowl Feb 24, 2026
4fbc07c
Merge remote-tracking branch 'origin/dev' into feature/70-remote-devc…
gerchowl Feb 24, 2026
a193036
Merge branch 'dev' into bugfix/186-missing-bandit-and-check-skill-names
gerchowl Feb 24, 2026
469685d
Merge remote-tracking branch 'origin/dev' into feature/70-remote-devc…
gerchowl Feb 24, 2026
98f4756
Merge branch 'bugfix/186-missing-bandit-and-check-skill-names' of git…
gerchowl Feb 24, 2026
6f796dc
Merge remote-tracking branch 'origin/dev' into feature/70-remote-devc…
gerchowl Feb 24, 2026
bda2c41
Merge branch 'bugfix/159-rich-missing-dependency' of github.com:vig-o…
gerchowl Feb 24, 2026
7c5c785
test: add failing test for devc-remote step-level progress logging
gerchowl Feb 24, 2026
0a7b6f6
fix: add step-level progress logging to devc-remote main pipeline
gerchowl Feb 24, 2026
df5026c
feat(remote): devcontainer orchestration, skills cleanup, and tooling…
gerchowl Feb 24, 2026
9715885
fix: make detect_editor_cli no-editor case deterministic
c-vigo Feb 25, 2026
137f226
fix(image): run lifecycle commands inside the container via bash
c-vigo Feb 25, 2026
5d61d9e
test: cover bash-wrapped devcontainer lifecycle commands
c-vigo Feb 25, 2026
db7cfdf
docs: update CHANGELOG
c-vigo Feb 25, 2026
afc668f
fix(image): run lifecycle commands inside the container via bash (#205)
c-vigo Feb 25, 2026
0257640
Merge remote-tracking branch 'origin/feature/70-remote-devc-orchestra…
gerchowl Feb 25, 2026
a253baf
fix: make detect_editor_cli no-editor case deterministic (#203)
gerchowl Feb 25, 2026
3e67e1d
chore: import additional worktree justfile for enhanced configuration
gerchowl Feb 26, 2026
b896cb0
Merge branch 'dev' of github.com:vig-os/devcontainer into feature/70-…
gerchowl Feb 26, 2026
93bad08
test: add failing test for terminal.integrated.defaultProfile.linux i…
gerchowl Feb 26, 2026
05cb2aa
fix(workspace): add terminal.integrated.defaultProfile.linux override…
gerchowl Feb 26, 2026
c2d386c
docs: update CHANGELOG for terminal profile override fix
gerchowl Feb 26, 2026
835ed30
fix(workspace): add terminal.integrated.defaultProfile.linux override…
gerchowl Feb 26, 2026
3ffe921
test: add BATS tests for setup-tailscale.sh
gerchowl Feb 26, 2026
50024c4
feat: add setup-tailscale.sh with install and start subcommands
gerchowl Feb 26, 2026
5800ee5
feat: hook setup-tailscale.sh install into post-create.sh
gerchowl Feb 26, 2026
da387ac
feat: hook setup-tailscale.sh start into post-start.sh
gerchowl Feb 26, 2026
8d0e437
docs: add commented Tailscale example to docker-compose.local.yaml
gerchowl Feb 26, 2026
db8c55f
docs: add Tailscale SSH section to devcontainer README
gerchowl Feb 26, 2026
d7741bc
docs: add Tailscale SSH changelog entry
gerchowl Feb 26, 2026
1950910
feat(podman): add push-ssh recipe to transfer images over SSH
gerchowl Feb 26, 2026
6995c39
feat: set default terminal profile to bash in devcontainer.json
gerchowl Feb 26, 2026
9760463
feat(podman): improve push-ssh validation and transfer progress
gerchowl Feb 26, 2026
0bea943
test(vigutils): add red tests for migrated scripts
c-vigo Mar 4, 2026
a352a68
feat(vigutils): migrate shared scripts into package entrypoints
c-vigo Mar 4, 2026
bd9958c
refactor(setup): switch callers to vig-utils entrypoints
c-vigo Mar 4, 2026
d131449
chore(setup): remove legacy script copies and superseded tests
c-vigo Mar 4, 2026
f3eb543
refactor(vigutils): consolidate agent fingerprint helpers into shared…
c-vigo Mar 4, 2026
a8d8957
chore(setup): remove legacy scripts/utils.py shim
c-vigo Mar 4, 2026
e5a1316
docs: update CHANGELOG
c-vigo Mar 4, 2026
4602d0a
fix(image): daemonize 'tailscaled' to survive postStartCommand exit
c-vigo Mar 6, 2026
be600dd
chore: merge branch 'dev' into feature/70-remote-devc-orchestration
c-vigo Mar 6, 2026
4fb1fbc
feat(podman): add arch detection and mismatch handling to push-ssh
gerchowl Mar 6, 2026
39850c2
Merge branch 'feature/70-remote-devc-orchestration' of github.com:vig…
gerchowl Mar 6, 2026
b76f3af
docs: add Tailscale SSH design document
gerchowl Mar 6, 2026
d3591e7
feat(remote): add Tailscale key injection and --open/--yes flags
gerchowl Mar 6, 2026
d9dc280
feat(remote): add --open ssh mode with Tailscale wait and connection …
gerchowl Mar 6, 2026
6b82c3b
feat(remote): auto-detect IDE from TERM_PROGRAM with fallback chain
gerchowl Mar 6, 2026
3d8c002
feat: add opt-in Tailscale SSH support to devcontainer (#208) (#211)
c-vigo Mar 7, 2026
1814b28
chore: merge branch 'dev' into feature/217-reorganize-scripts-vig-utils
c-vigo Mar 7, 2026
30c029f
fix(ci): allow dotfile paths and doc filenames in agent blocklist
gerchowl Mar 7, 2026
9930815
feat(remote): IDE-agnostic --open ssh mode with Tailscale wait (#234)
gerchowl Mar 7, 2026
b041afa
feat(remote): Tailscale key injection and --open/--yes flags (#233)
gerchowl Mar 7, 2026
e9c9da4
test: improve coverage for agent blocklist and shell entrypoints
gerchowl Mar 7, 2026
67a4da6
Merge remote-tracking branch 'origin/dev' into feature/70-remote-devc…
gerchowl Mar 7, 2026
0ea692a
Merge remote-tracking branch 'origin/feature/217-reorganize-scripts-v…
gerchowl Mar 7, 2026
c4c03f3
feat(remote): add container lifecycle execution and compose file parsing
gerchowl Mar 8, 2026
d530de6
feat(remote): add opt-in Claude Code CLI with subscription OAuth auth
gerchowl Mar 8, 2026
0b3f5bc
chore: add .worktrees/ to gitignore
gerchowl Mar 8, 2026
26d3ea7
test(remote): add failing tests for --bootstrap flag and bootstrap flow
gerchowl Mar 8, 2026
88b077f
feat(remote): add --bootstrap for one-time remote host setup with con…
gerchowl Mar 8, 2026
42d3e75
chore: add .worktrees/ to gitignore
gerchowl Mar 8, 2026
83dbb32
test(remote): add failing tests for gh: target arg parsing
gerchowl Mar 8, 2026
00e2664
feat(remote): add gh:org/repo[:branch] arg parsing to parse_args
gerchowl Mar 8, 2026
fd64108
test(remote): add failing tests for remote_clone_project function
gerchowl Mar 8, 2026
5fb12e2
feat(remote): implement remote_clone_project and wire into main pipeline
gerchowl Mar 8, 2026
7702775
docs(remote): add gh: target syntax to help text and changelog
gerchowl Mar 9, 2026
364de3e
Merge branch 'feature/235-bootstrap-remote' into feature/70-remote-de…
gerchowl Mar 9, 2026
4620c39
Merge branch 'feature/236-remote-gh-clone-target' into feature/70-rem…
gerchowl Mar 9, 2026
17ca79f
fix(remote): use sentinels for SSH arg passing in remote_clone_project
gerchowl Mar 9, 2026
9280224
feat(remote): forward GHCR auth on every deploy, not just bootstrap
gerchowl Mar 9, 2026
a6f140a
feat(remote): add --force flag, unpushed commits guard, and just remo…
gerchowl Mar 9, 2026
c209f1d
fix(remote): use real TUN for Tailscale SSH instead of userspace netw…
gerchowl Mar 9, 2026
501b0ef
fix(remote): ensure TUN device config added to existing Tailscale com…
gerchowl Mar 9, 2026
0b0bcef
fix(remote): always regenerate Tailscale key and prefer podman-compose
gerchowl Mar 9, 2026
15120fb
fix(remote): ensure ~/.local/bin in PATH for SSH compose commands
gerchowl Mar 9, 2026
ea3af49
refactor(remote): revert unnecessary podman-compose preference
gerchowl Mar 9, 2026
49c7a4e
feat(remote): pre-flight check for stale local Tailscale
gerchowl Mar 9, 2026
d44cf31
docs: regenerate README and CONTRIBUTE with remote-devc recipe
gerchowl Mar 12, 2026
41b6423
fix(tests): bump expected gh version to 2.88
gerchowl Mar 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ scripts/build.sh @c-vigo
scripts/prepare-build.sh @c-vigo
scripts/clean.sh @c-vigo
scripts/sync_manifest.py @c-vigo
scripts/utils.py @c-vigo

# Developer tooling scripts
scripts/gh_issues.py @gerchowl
scripts/setup-labels.sh @gerchowl
scripts/resolve-branch.sh @gerchowl
packages/vig-utils/src/vig_utils/gh_issues.py @gerchowl
packages/vig-utils/src/vig_utils/setup_labels.py @gerchowl
packages/vig-utils/src/vig_utils/shell/setup-labels.sh @gerchowl
packages/vig-utils/src/vig_utils/resolve_branch.py @gerchowl
packages/vig-utils/src/vig_utils/shell/resolve-branch.sh @gerchowl

# Dev environment setup
scripts/init.sh @c-vigo
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/test-project/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ runs:
run: |
uv run pytest \
tests/test_utils.py \
tests/test_gh_issues.py \
tests/test_devc_remote_uri.py \
packages/vig-utils/tests \
--cov --cov-report=term-missing --cov-report=xml \
$TEST_ARGS
Expand Down
4 changes: 2 additions & 2 deletions .github/label-taxonomy.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Canonical repository labels.
# Single source of truth — referenced by:
# - scripts/setup-labels.sh (provision labels on a repo)
# - uv run setup-labels (provision labels on a repo)
# - .cursor/skills/issue_triage/SKILL.md (triage label check)
# - .cursor/skills/issue_create/SKILL.md (agent label mapping)
# - .github/ISSUE_TEMPLATE/*.yml (template label values)
#
# Label reconciliation:
# Run `scripts/setup-labels.sh` after repo creation to create/update labels
# Run `uv run setup-labels` after repo creation to create/update labels
# from this taxonomy. Use `--prune` to remove org-default labels that don't
# match the taxonomy. Use `--dry-run` to preview changes first.

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-title-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ jobs:
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_BODY: ${{ github.event.pull_request.body }}
run: uv run python scripts/check-pr-agent-fingerprints.py
run: uv run check-pr-agent-fingerprints
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -223,5 +223,8 @@ __marimo__/
# Pre-commit cache
.pre-commit-cache/

# Worktrees
.worktrees/

# Bats
node_modules/
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ repos:
hooks:
- id: bandit
name: bandit (Python security linting)
entry: uv run bandit -r packages/vig-utils/src/ scripts/ assets/workspace/ -ll
entry: uv run bandit -r packages/vig-utils/src/ assets/workspace/ -ll
language: system
types: [python]
pass_filenames: false
Expand All @@ -160,8 +160,8 @@ repos:
hooks:
- id: check-skill-names
name: check-skill-names (enforce naming convention)
entry: scripts/check-skill-names.sh .cursor/skills
language: script
entry: uv run check-skill-names .cursor/skills
language: system
files: ^\.cursor/skills/
pass_filenames: false

Expand All @@ -170,7 +170,7 @@ repos:
hooks:
- id: prepare-commit-msg-strip-trailers
name: strip agent trailers from commit message
entry: uv run python scripts/prepare-commit-msg-strip-trailers.py
entry: uv run prepare-commit-msg-strip-trailers
language: system
stages: [prepare-commit-msg]
pass_filenames: true
Expand All @@ -180,7 +180,7 @@ repos:
hooks:
- id: check-agent-identity
name: check agent identity
entry: uv run python scripts/check-agent-identity.py
entry: uv run check-agent-identity
language: system
pass_filenames: false

Expand Down
161 changes: 161 additions & 0 deletions CHANGELOG.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions CONTRIBUTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,11 @@ Available recipes:
update # Update all dependencies

[devcontainer]
devc-remote *args # just devc-remote --repo [email protected]:org/repo.git myserver
down # Stop and remove containers
logs *args # Tail container logs
open # Open Cursor/VS Code attached to the running container
remote-devc host *args # just remote-devc ksb-meatgrinder --open none
restart *args # Restart service(s)
shell # Open bash in running devcontainer
status # Show container status
Expand Down Expand Up @@ -202,6 +204,7 @@ Available recipes:
podman-prune # Prune unused containers, images, networks, and volumes [alias: pdm-prune]
podman-prune-all # Full cleanup: prune including volumes [alias: pdm-prune-all]
podman-ps *args # List containers/images (--all for all podman resources) [alias: pdm-ps]
podman-push-ssh image host # Push a local image to a remote machine over SSH (no registry needed) [alias: pdm-push-ssh]
podman-rmi image # Remove an image by name, tag, or ID [alias: pdm-rmi]
podman-rmi-all # Remove all images (with confirmation) [alias: pdm-rmi-all]
podman-rmi-dangling # Remove dangling images (untagged) [alias: pdm-rmi-dangling]
Expand Down
4 changes: 4 additions & 0 deletions Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
git \
jq \
openssh-client \
locales \
ca-certificates \
Expand Down Expand Up @@ -214,6 +215,9 @@ RUN set -eux; \
tar -xzf "$FILE" -C /usr/local/bin --strip-components=1; \
rm "$FILE";

# Copy vig-utils package early so uv can resolve the workspace member
COPY packages/vig-utils /root/packages/vig-utils

# Install Python development tools from root pyproject.toml (SSoT)
# and upgrade pip to fix CVE-2025-8869 (symbolic link extraction vulnerability)
# vig-utils must be present before uv export because uv.lock references it as a workspace member
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,11 @@ Available recipes:
update # Update all dependencies

[devcontainer]
devc-remote *args # just devc-remote --repo [email protected]:org/repo.git myserver
down # Stop and remove containers
logs *args # Tail container logs
open # Open Cursor/VS Code attached to the running container
remote-devc host *args # just remote-devc ksb-meatgrinder --open none
restart *args # Restart service(s)
shell # Open bash in running devcontainer
status # Show container status
Expand Down Expand Up @@ -153,6 +155,7 @@ Available recipes:
podman-prune # Prune unused containers, images, networks, and volumes [alias: pdm-prune]
podman-prune-all # Full cleanup: prune including volumes [alias: pdm-prune-all]
podman-ps *args # List containers/images (--all for all podman resources) [alias: pdm-ps]
podman-push-ssh image host # Push a local image to a remote machine over SSH (no registry needed) [alias: pdm-push-ssh]
podman-rmi image # Remove an image by name, tag, or ID [alias: pdm-rmi]
podman-rmi-all # Remove all images (with confirmation) [alias: pdm-rmi-all]
podman-rmi-dangling # Remove dangling images (untagged) [alias: pdm-rmi-dangling]
Expand Down
2 changes: 1 addition & 1 deletion assets/init-workspace.sh
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ if [[ "$FORCE" == "true" ]]; then
CONFLICTS+=("$rel_path")
fi
fi
done < <(find "$TEMPLATE_DIR" -type f ! -path "*/.git/*" -print0)
done < <(find "$TEMPLATE_DIR" -type f ! -path "*/.git/*" ! -path "*/.venv/*" -print0)

# Show preserved files
if [[ ${#PRESERVED[@]} -gt 0 ]]; then
Expand Down
60 changes: 60 additions & 0 deletions assets/workspace/.devcontainer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,66 @@ Paths to other mounts can be absolute or relative to the main project folder.
projects you want to see in the editor. The file is git-ignored, so your personal
configuration stays local.

## Tailscale SSH

Connect to the devcontainer over Tailscale SSH instead of the devcontainer protocol.
This enables tools like Cursor GUI to execute shell commands inside the container via SSH remote.

### Prerequisites

1. A [Tailscale](https://tailscale.com/) account with SSH enabled in your tailnet ACLs.
2. An auth key (ephemeral + reusable recommended) from
[Tailscale Admin → Settings → Keys](https://login.tailscale.com/admin/settings/keys).

### Setup

1. Add the auth key to your local compose override (git-ignored):

```yaml
# .devcontainer/docker-compose.local.yaml
services:
devcontainer:
environment:
- TAILSCALE_AUTHKEY=tskey-auth-XXXX
# Optional: override the auto-generated hostname
# - TAILSCALE_HOSTNAME=myproject-devc-mybox
```

2. Rebuild the devcontainer (`Cmd/Ctrl+Shift+P` → "Dev Containers: Rebuild Container").

3. Tailscale installs on first create (~10 s) and connects on every start.
The container appears in your tailnet as `<project>-devc-<hostname>`.

4. Connect via SSH from Cursor or any SSH client:

```bash
ssh root@<tailscale-hostname>
```

### Tailscale ACL configuration

Your tailnet must allow SSH access. Add a rule like this to your
[ACL policy](https://login.tailscale.com/admin/acls):

```json
{
"ssh": [
{
"action": "accept",
"src": ["autogroup:members"],
"dst": ["autogroup:self"],
"users": ["root", "autogroup:nonroot"]
}
]
}
```

### How it works

- `setup-tailscale.sh install` runs during `postCreateCommand` — installs Tailscale if `TAILSCALE_AUTHKEY` is set.
- `setup-tailscale.sh start` runs during `postStartCommand` — starts `tailscaled` (userspace networking, no `/dev/net/tun` needed) and authenticates.
- When `TAILSCALE_AUTHKEY` is unset, both hooks are silent no-ops.

## Updating the template

If you synchronize with a newer release of the vigOS devcontainer image,
Expand Down
7 changes: 4 additions & 3 deletions assets/workspace/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"nefrob.vscode-just-syntax"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"python.defaultInterpreterPath": "/root/assets/workspace/.venv/bin/python",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff",
Expand Down Expand Up @@ -50,7 +51,7 @@
"--group-add=0"
],
"initializeCommand": ".devcontainer/scripts/initialize.sh",
"postStartCommand": "/workspace/{{SHORT_NAME}}/.devcontainer/scripts/post-start.sh",
"postAttachCommand": "/workspace/{{SHORT_NAME}}/.devcontainer/scripts/post-attach.sh",
"postCreateCommand": "/workspace/{{SHORT_NAME}}/.devcontainer/scripts/post-create.sh"
"postStartCommand": "/bin/bash /workspace/{{SHORT_NAME}}/.devcontainer/scripts/post-start.sh",
"postAttachCommand": "/bin/bash /workspace/{{SHORT_NAME}}/.devcontainer/scripts/post-attach.sh",
"postCreateCommand": "/bin/bash /workspace/{{SHORT_NAME}}/.devcontainer/scripts/post-create.sh"
}
25 changes: 25 additions & 0 deletions assets/workspace/.devcontainer/docker-compose.local.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,29 @@
# environment:
# - MY_API_KEY=secret123

# Optional: Tailscale SSH for direct mesh access (e.g. Cursor GUI workaround)
# Generate an auth key at https://login.tailscale.com/admin/settings/keys
# Use an ephemeral + reusable key so stale containers auto-expire.
# The device + cap_add entries are required for Tailscale SSH to work (real TUN).
#
# services:
# devcontainer:
# devices:
# - /dev/net/tun:/dev/net/tun
# cap_add:
# - NET_ADMIN
# - NET_RAW
# environment:
# - TAILSCALE_AUTHKEY=tskey-auth-XXXX
# - TAILSCALE_HOSTNAME=myproject-devc-mybox # optional override

# Optional: Claude Code CLI (subscription OAuth token)
# Run `claude setup-token` on your host to generate a long-lived token (1 year).
# devc-remote.sh auto-injects from your local CLAUDE_CODE_OAUTH_TOKEN env var.
#
# services:
# devcontainer:
# environment:
# - CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-XXXX

services: {}
46 changes: 45 additions & 1 deletion assets/workspace/.devcontainer/justfile.base
Original file line number Diff line number Diff line change
Expand Up @@ -366,4 +366,48 @@ sidecar name *args:
fi

# Execute the recipe in the sidecar
podman exec {{ name }} just {{ args }}
podman exec {{name}} just {{args}}

# -------------------------------------------------------------------------------
# REMOTE DEVCONTAINER
# -------------------------------------------------------------------------------

# Start a devcontainer on a remote host and open Cursor/VS Code
# Auto-clones the repo and runs init-workspace if needed
# Usage: just devc-remote myserver
# just devc-remote myserver:/home/user/repo
# just devc-remote --repo [email protected]:org/repo.git myserver
[group('devcontainer')]
devc-remote *args:
bash scripts/devc-remote.sh {{args}}

# Deploy current project to a remote host (auto-detects repo + branch)
# Pushes unpushed commits, clones/fetches on remote, starts devcontainer
# Usage: just remote-devc <ssh-host>[:<path>] [extra-args...]
# Example: just remote-devc ksb-meatgrinder
# just remote-devc ksb-meatgrinder --open none
[group('devcontainer')]
remote-devc host *args:
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "{{source_directory()}}/scripts" && pwd)"
if [[ ! -f "$SCRIPT_DIR/devc-remote.sh" ]]; then
echo "[ERROR] devc-remote.sh not found at $SCRIPT_DIR"
exit 1
fi
# Auto-detect org/repo from git remote
remote_url=$(git remote get-url origin 2>/dev/null) || {
echo "[ERROR] No git remote 'origin' found. Run from inside a git repo."
exit 1
}
# Extract org/repo from SSH or HTTPS URL
# ssh: [email protected]:org/repo.git → org/repo
# https: https://github.com/org/repo.git → org/repo
gh_repo=$(echo "$remote_url" | sed -E 's#(git@|https://)([^:/]+)[:/]##; s/\.git$//')
# Auto-detect current branch
branch=$(git branch --show-current 2>/dev/null)
gh_target="gh:${gh_repo}"
if [[ -n "$branch" ]]; then
gh_target="gh:${gh_repo}:${branch}"
fi
bash "$SCRIPT_DIR/devc-remote.sh" --force "{{host}}" "$gh_target" {{args}}
4 changes: 1 addition & 3 deletions assets/workspace/.devcontainer/justfile.gh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

alias gh-i := gh-issues

_gh_scripts := source_directory() / "scripts"

# List open issues and PRs grouped by milestone
[group('github')]
gh-issues:
uv run python {{ _gh_scripts }}/gh_issues.py
gh-issues
Loading