Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .delphi/manifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# MINOR something new that existing clones need nothing for
# MAJOR clones need cleanup (MINOR while 0.x): add .delphi/migrations/<version>-<slug>.sh, which
# setup.sh runs once per workspace in each clone (rules in Delphi's CLAUDE.md)
version: 0.8.0
version: 0.9.0
files: # repo-relative paths; a trailing / means everything under it
- .delphi/manifest.yml
- .delphi/.gitattributes
Expand Down
25 changes: 25 additions & 0 deletions .delphi/migrations/0.9.0-linked-clones.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
# 0.9.0: linked/<name> used to be a shallow, detached, push-disabled copy of ws/<name> (or main);
# setup.sh now keeps a full clone there, on that branch and tracking origin, with pushes allowed. Turns
# each old copy here (its push URL is DISABLED-read-only-copy) into one in place: fetches its full
# history, puts it on a local ws/<name> (or main) at the commit it's on, so nothing in it moves, and
# allows pushes. setup.sh then pulls it. Parked copies are their own workspace's, migrated when it's
# set up. Stops at one it can't fetch or that already has a local branch of that name.
set -euo pipefail
for d in linked/*/; do
d=${d%/}
[ -d "$d/.git" ] || continue
[ "$(git -C "$d" config remote.origin.pushurl || true)" = DISABLED-read-only-copy ] || continue # a clone already
n=${d#linked/} ref=ws/${d#linked/} unshallow=
[ "$n" != main ] || ref=main
[ "$(git -C "$d" rev-parse --is-shallow-repository)" = false ] || unshallow=--unshallow
git -C "$d" fetch -q ${unshallow:+"$unshallow"} origin "+refs/heads/$ref:refs/remotes/origin/$ref" </dev/null ||
{ echo "migrate: could not fetch $ref into $d; re-run setup when you can reach origin" >&2 && exit 1; }
if [ -z "$(git -C "$d" branch --show-current)" ]; then
git -C "$d" switch -q -c "$ref" 2>/dev/null ||
{ echo "migrate: $d already has a branch $ref; git -C $d switch $ref (or delete it), then re-run setup" >&2 && exit 1; }
fi
! git -C "$d" rev-parse -q --verify "refs/heads/$ref" >/dev/null || git -C "$d" branch -q -u "origin/$ref" "$ref"
git -C "$d" config --unset-all remote.origin.pushurl
echo "migrate: $d is a full clone on $ref now"
done
2 changes: 1 addition & 1 deletion .delphi/paths.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ DELPHI_ROOT=$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")/.." && pwd)
DELPHI_REPOS=$DELPHI_ROOT/repos # bare stores: repos/<repo>
DELPHI_WORKTREES=$DELPHI_ROOT/worktrees # checkouts: worktrees/<repo>/<branch>
DELPHI_REFERENCES=$DELPHI_ROOT/references # read-only dependency sources: references/<name>
DELPHI_LINKED=$DELPHI_ROOT/linked # read-only Delphi copies: linked/<workspace>, linked/main
DELPHI_LINKED=$DELPHI_ROOT/linked # Delphi clones to read: linked/<workspace>, linked/main
export DELPHI_ROOT DELPHI_REPOS DELPHI_WORKTREES DELPHI_REFERENCES DELPHI_LINKED
[ "${BASH_SOURCE[0]:-}" != "$0" ] || printf 'export DELPHI_ROOT=%q DELPHI_REPOS=%q DELPHI_WORKTREES=%q DELPHI_REFERENCES=%q DELPHI_LINKED=%q\n' \
"$DELPHI_ROOT" "$DELPHI_REPOS" "$DELPHI_WORKTREES" "$DELPHI_REFERENCES" "$DELPHI_LINKED"
20 changes: 16 additions & 4 deletions .delphi/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
# `references-git:` (read-only dependency sources, `<name>: <git-url> [<ref>]`), checks out a shallow,
# detached copy of <ref> (default: origin's default branch) at references/<name>, refreshed on every
# run, with pushes disabled. Each entry under `workspaces:` (`- <name>`, a workspace's dotted name
# from .delphi/names.sh, or `- main`) gets the same kind of copy of that branch of this clone's
# origin (Delphi, ws/<name> or main), at linked/<name>; to edit one, switch this clone to it (.delphi/switch.sh). Adds the
# from .delphi/names.sh, or `- main`) gets a full clone of this clone's origin (Delphi) at linked/<name>,
# on ws/<name> (or main) tracking origin; every run switches it back to that branch if it was switched
# away (its own .delphi/switch.sh) and pulls it. By convention it's read from here, not edited. Adds the
# folders park.sh parks and macOS's .DS_Store to this clone's .git/info/exclude, and writes its post-checkout hook, which runs .delphi/park.sh (on
# every branch) as just checked out in the worktree that checked out (unless another hook is there), so switching
# to another workspace or main parks those folders. First
Expand Down Expand Up @@ -68,11 +69,22 @@ readonly_copy() { # <dir> <url> [<ref>]: shallow, detached, push-disabled checko
fi
}

link() { # <name>|main: a read-only copy of that workspace's branch of Delphi (ws/<name>), or main, at linked/<name>
link() { # <name>|main: a clone of Delphi on that workspace's branch (ws/<name>), or main, at linked/<name>
case "$1" in "$self") return ;; "" | [-.]* | *. | *..* | *[!a-z0-9.-]*)
echo "setup: skipping bad workspaces: entry '$1' (want a workspace's name, like s.app.argos.argos-dev, or main)" >&2 && return ;;
esac
readonly_copy "linked/$1" "$(git remote get-url origin)" "$([ "$1" = main ] && echo main || echo "ws/$1")"
local dir=linked/$1 ref=ws/$1
[ "$1" != main ] || ref=main
[ ! -f "$dir/.git" ] || { echo "setup: $dir is a worktree, not a clone; skipping it" >&2 && return; }
if [ ! -d "$dir/.git" ]; then
git clone -q --branch "$ref" "$(git remote get-url origin)" "$dir" </dev/null ||
{ echo "setup: could not clone $ref into $dir" >&2 && return; }
elif [ "$(git -C "$dir" branch --show-current)" != "$ref" ]; then # switched away: back to its own branch first
bash "$dir/.delphi/switch.sh" "$1" </dev/null >/dev/null ||
{ echo "setup: could not switch $dir back to $ref; left it as it is" >&2 && return; }
fi
git -C "$dir" pull -q --ff-only origin "$ref" </dev/null || echo "setup: could not pull $ref into $dir (see git -C $dir status)" >&2
echo "$dir: on $ref ($(git -C "$dir" rev-parse --short HEAD))"
}

while read -r kind name url ref; do
Expand Down
1 change: 1 addition & 0 deletions .delphi/versions
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@
0.6.0 c65ffc578bfa setup.sh (.delphi/plugins.sh) makes each clone's @delphi plugins what its workspace enables (installs them, uninstalls local ones it doesn't) and uninstalls ones the marketplace dropped, instead of warning; plugin changes need no migration
0.7.0 84df5ce802db park.sh also parks .journal/ and the root folders under a workspace's park: in workspace.yml (each workspace its own), restores everything parked for a workspace, and skips bad entries; setup.sh excludes them
0.8.0 05d4c954a946 workspaces are named by their folders' short names and leaf, joined by dots (.delphi/names.sh, short-name files; ws/s.app.argos.argos-dev, was ws/software/…/argos-dev); workspaces: entries are - <name> | - main, copied to linked/<name>; sync carries ws/<old> over once (migration)
0.9.0 b850821eaa9a linked/<name> are full clones on ws/<name> (or main) tracking origin, pushes allowed; setup.sh switches each back to its branch if switched away and pulls it (migration)
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,18 @@ repos: # stored in repos/<name>, checked out in worktrees/<name
argos: https://github.com/Northeastern-Electric-Racing/Argos.git
references-git: # read-only dependency sources, shallow-cloned into references/<name>/
socketioxide: https://github.com/Totodore/socketioxide.git v0.18.7 # optional tag or branch
workspaces: # Delphi workspaces (by name) or main, read-only, shallow-cloned into linked/<name>/
workspaces: # Delphi workspaces (by name) or main, cloned into linked/<name>/ to read
- main
```

`repos:` are the code you change. `references-git:` are open-source dependencies the agent reads for
context: `setup.sh` checks each out shallow and detached at its pin (or the default branch), with
pushes disabled, and refreshes them on every run. They get no store and no worktrees. Names are
unique across both maps. The `-git` suffix leaves room for other kinds of references later.
`workspaces:` are other workspaces (`- <name>`) or `main` to read: the same kind of read-only copy, of Delphi itself.
To change one, switch to it instead.
`workspaces:` are other workspaces (`- <name>`) or `main` to read: full clones of Delphi itself, each on
its branch (`ws/<name>` or `main`) tracking origin, so `git status` and `git log` work as usual. Every
run switches a clone back to its branch if it was switched away and pulls it. By convention they aren't
edited from the workspace that links them; to change one, work in its own clone or switch to it.

The workspace's dotted name is repeated in `name:` so a checkout knows which workspace it is; names
are unique (give a folder a `short-name` that no sibling's name or short name clashes with). Every other file in the folder is the workspace's own, at its normal harness
Expand Down
8 changes: 6 additions & 2 deletions docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,12 @@ sources), it fetches `<ref>` (default: origin's `HEAD`) with `--depth 1` into `r
checks it out detached, disables pushes, and does this again on every run, so the copy tracks its pin;
a failed fetch is reported and the old copy kept. Adds `/references/` to the exclude too; references get
no store and no worktrees (`new-worktree.sh` refuses them). Each entry under `workspaces:` (`- <name>`
or `- main`; the workspace itself is skipped) gets the same kind of copy of that branch (`ws/<name>`
or `main`) of the clone's own origin, at `linked/<name>/`, also refreshed every run; `/linked/` is excluded too.
or `- main`; the workspace itself is skipped) gets a full clone of the clone's own origin at
`linked/<name>/`, on that branch (`ws/<name>` or `main`) tracking origin, so it behaves as a normal
checkout (`git status` shows its branch). Every run switches it back to that branch if it was switched
away (with its own `.delphi/switch.sh`, which refuses over uncommitted changes) and pulls it
(`--ff-only`); a failure is reported and the clone left as it is. By convention a workspace reads its
links and doesn't edit them; `/linked/` is excluded too.
Links are separate clones, not worktrees of the Delphi clone, so two workspaces can both link `main`
and each copy parks with its workspace. Writes the clone's `post-checkout` hook, a 3-line script that
runs `.delphi/park.sh` from the worktree that checked out (replacing an older link to or copy of a
Expand Down
2 changes: 1 addition & 1 deletion software/application-software/argos/AUTHORING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ a PR to `main`. Trim what the new workspace doesn't need before merging.
## Change the defaults or this folder

Edit on a branch of `main` and open a PR to `main` (from a workspace: `bash .delphi/switch.sh main`;
`linked/main/` is read-only). `workspace-defaults/`
don't edit `linked/main/` from a workspace). `workspace-defaults/`
only affects workspaces created afterwards; to change existing ones, PR each workspace too. `workspace-inherit/` reaches
every Argos workspace on the next sync.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ park: # `- <folder>`: root folders that park with this works
repos: # `<name>: <git-url>`: code you change; bare store at repos/<name>, default branch at worktrees/<name>/<branch>
argos: https://github.com/Northeastern-Electric-Racing/Argos.git
odyssey-definitions: https://github.com/Northeastern-Electric-Racing/Odyssey-Definitions.git # CAN definitions for verify-telemetry
workspaces: # `- <name>` (dotted) or `- main`: Delphi workspaces to read, never edit; shallow copy at linked/<name or main>
workspaces: # `- <name>` (dotted) or `- main`: Delphi workspaces to read, not edit from here; a clone on its branch at linked/<name or main>
- main
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Delphi workspace

You're in Delphi workspace `s.app.argos.argos-dev` (branch `ws/s.app.argos.argos-dev`); code repos are checked out as worktrees under `worktrees/<repo>/` (`.delphi/setup.sh` makes the default branch's). Make new branches as worktrees (`new-worktree` skill) unless the user says not to. Delphi workspaces (or `main`) under `workspaces:` in `workspace.yml` (`- <name>`, a workspace's dotted name like `s.app.argos.argos-dev`, or `- main`) are read-only copies at `linked/<name>/` for reading their context; change what's checked out with the `setup-workspace` skill. To work in another workspace, switch this clone to it (`switch-workspace` skill). Park rough notes with the `journal` skill. Work here unless the task clearly belongs to another project.
You're in Delphi workspace `s.app.argos.argos-dev` (branch `ws/s.app.argos.argos-dev`); code repos are checked out as worktrees under `worktrees/<repo>/` (`.delphi/setup.sh` makes the default branch's). Make new branches as worktrees (`new-worktree` skill) unless the user says not to. Delphi workspaces (or `main`) under `workspaces:` in `workspace.yml` (`- <name>`, a workspace's dotted name like `s.app.argos.argos-dev`, or `- main`) are clones at `linked/<name>/`, each on its branch, for reading their context (don't edit them from here; setup switches each back to its branch and pulls it); change what's checked out with the `setup-workspace` skill. To work in another workspace, switch this clone to it (`switch-workspace` skill). Park rough notes with the `journal` skill. Work here unless the task clearly belongs to another project.

Always work from the workspace root (this clone's top, where `workspace.yml` is); the layout exists so one session can reach every worktree from there. Name worktrees by path: `git -C worktrees/argos/<branch> …` runs git there without moving, and a one-off subshell like `(cd worktrees/argos/<branch>/angular-client && npx ng lint)` runs anything else. If you `cd` into a worktree to look closely at something, `cd` back to the root as soon as you're done. Skill scripts take only names (repo, branch) and find the rest from `$DELPHI_ROOT`, which a session hook sets in every shell (`$DELPHI_WORKTREES` and the other `.delphi/paths.sh` folders too).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ references-git: # `<name>: <git-url> [<tag-or-branch>]`: dependency so
socketioxide: https://github.com/Totodore/socketioxide.git socketioxide-v0.18.7
socket.io: https://github.com/socketio/socket.io.git socket.io-client@4.8.1 # monorepo: client, server, engine.io, parser
zenoh: https://github.com/eclipse-zenoh/zenoh.git 1.10.1
workspaces: # `- <name>` (dotted) or `- main`: Delphi workspaces to read, never edit; shallow copy at linked/<name or main>
workspaces: # `- <name>` (dotted) or `- main`: Delphi workspaces to read, not edit from here; a clone on its branch at linked/<name or main>
- main
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Delphi workspace

You're in Delphi workspace `s.app.argos.experimental` (branch `ws/s.app.argos.experimental`); code repos are checked out as worktrees under `worktrees/<repo>/` (`.delphi/setup.sh` makes the default branch's). Make new branches as worktrees (`new-worktree` skill) unless the user says not to. Delphi workspaces (or `main`) under `workspaces:` in `workspace.yml` (`- <name>`, a workspace's dotted name like `s.app.argos.argos-dev`, or `- main`) are read-only copies at `linked/<name>/` for reading their context; change what's checked out with the `setup-workspace` skill. To work in another workspace, switch this clone to it (`switch-workspace` skill). Park rough notes with the `journal` skill. Work here unless the task clearly belongs to another project.
You're in Delphi workspace `s.app.argos.experimental` (branch `ws/s.app.argos.experimental`); code repos are checked out as worktrees under `worktrees/<repo>/` (`.delphi/setup.sh` makes the default branch's). Make new branches as worktrees (`new-worktree` skill) unless the user says not to. Delphi workspaces (or `main`) under `workspaces:` in `workspace.yml` (`- <name>`, a workspace's dotted name like `s.app.argos.argos-dev`, or `- main`) are clones at `linked/<name>/`, each on its branch, for reading their context (don't edit them from here; setup switches each back to its branch and pulls it); change what's checked out with the `setup-workspace` skill. To work in another workspace, switch this clone to it (`switch-workspace` skill). Park rough notes with the `journal` skill. Work here unless the task clearly belongs to another project.

# NER Software conventions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ park: # `- <folder>`: root folders that park with this works
repos: # `<name>: <git-url>`: code you change; bare store at repos/<name>, default branch at worktrees/<name>/<branch>
argos: https://github.com/Northeastern-Electric-Racing/Argos.git
odyssey-definitions: https://github.com/Northeastern-Electric-Racing/Odyssey-Definitions.git
workspaces: # `- <name>` (dotted) or `- main`: Delphi workspaces to read, never edit; shallow copy at linked/<name or main>
workspaces: # `- <name>` (dotted) or `- main`: Delphi workspaces to read, not edit from here; a clone on its branch at linked/<name or main>
- main
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Delphi workspace

You're in Delphi workspace `s.app.nero.nero-experimental` (branch `ws/s.app.nero.nero-experimental`); code repos are checked out as worktrees under `worktrees/<repo>/` (`.delphi/setup.sh` makes the default branch's). Make new branches as worktrees (`new-worktree` skill) unless the user says not to. Delphi workspaces (or `main`) under `workspaces:` in `workspace.yml` (`- <name>`, a workspace's dotted name like `s.app.argos.argos-dev`, or `- main`) are read-only copies at `linked/<name>/` for reading their context; change what's checked out with the `setup-workspace` skill. To work in another workspace, switch this clone to it (`switch-workspace` skill). Park rough notes with the `journal` skill. Work here unless the task clearly belongs to another project.
You're in Delphi workspace `s.app.nero.nero-experimental` (branch `ws/s.app.nero.nero-experimental`); code repos are checked out as worktrees under `worktrees/<repo>/` (`.delphi/setup.sh` makes the default branch's). Make new branches as worktrees (`new-worktree` skill) unless the user says not to. Delphi workspaces (or `main`) under `workspaces:` in `workspace.yml` (`- <name>`, a workspace's dotted name like `s.app.argos.argos-dev`, or `- main`) are clones at `linked/<name>/`, each on its branch, for reading their context (don't edit them from here; setup switches each back to its branch and pulls it); change what's checked out with the `setup-workspace` skill. To work in another workspace, switch this clone to it (`switch-workspace` skill). Park rough notes with the `journal` skill. Work here unless the task clearly belongs to another project.

# NER Software conventions

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ park: # `- <folder>`: root folders that park with this works
# .delphi/setup.sh checks out everything below (git-ignored); re-run it after any change.
repos: # `<name>: <git-url>`: code you change; bare store at repos/<name>, default branch at worktrees/<name>/<branch>
nero: https://github.com/Northeastern-Electric-Racing/Nero-2.0.git
workspaces: # `- <name>` (dotted) or `- main`: Delphi workspaces to read, never edit; shallow copy at linked/<name or main>
workspaces: # `- <name>` (dotted) or `- main`: Delphi workspaces to read, not edit from here; a clone on its branch at linked/<name or main>
# - main
4 changes: 2 additions & 2 deletions software/application-software/workspaces/hub/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ one under `repos:` in `workspace.yml` to make worktrees here (`new-worktree` ski

Each workspace listed under `workspaces:` in `workspace.yml` is also cloned separately on this machine, on its
own `ws/<name>` branch, with its own Claude Code session. The user works in those in parallel. Here you
only see their read-only copies under `linked/<name>/` (refresh with `bash .delphi/setup.sh`; change which are
only see their clones under `linked/<name>/`, each on its branch (refresh with `bash .delphi/setup.sh`; change which are
listed with the `setup-workspace` skill). Park rough notes with the `journal` skill.

## What you do here
Expand All @@ -24,4 +24,4 @@ listed with the `setup-workspace` skill). Park rough notes with the `journal` sk

- Switch this clone to another workspace unless the user explicitly asks (`switch-workspace`). By default,
hand off: the user relaunches Claude in that workspace's own clone.
- Edit anything under `linked/`.
- Edit, commit, or push anything under `linked/`: the user may work in those clones, but not this session.
Loading
Loading