Compare commits
2 Commits
8318e60c33
...
5be7b84972
| Author | SHA1 | Date | |
|---|---|---|---|
| 5be7b84972 | |||
| ae077886ba |
44
AGENTS.md
Normal file
44
AGENTS.md
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
# Agent Instructions
|
||||||
|
|
||||||
|
Read and follow the instructions in `diachron/AGENTS.md`. That file
|
||||||
|
contains framework conventions, commands, and structure that apply to
|
||||||
|
all coding agents working on diachron-based projects.
|
||||||
|
|
||||||
|
This project uses **bd** (beads) for issue tracking. Run `bd onboard` to get started.
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bd ready # Find available work
|
||||||
|
bd show <id> # View issue details
|
||||||
|
bd update <id> --status in_progress # Claim work
|
||||||
|
bd close <id> # Complete work
|
||||||
|
bd sync # Sync with git
|
||||||
|
```
|
||||||
|
|
||||||
|
## Landing the Plane (Session Completion)
|
||||||
|
|
||||||
|
**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
|
||||||
|
|
||||||
|
**MANDATORY WORKFLOW:**
|
||||||
|
|
||||||
|
1. **File issues for remaining work** - Create issues for anything that needs follow-up
|
||||||
|
2. **Run quality gates** (if code changed) - Tests, linters, builds
|
||||||
|
3. **Update issue status** - Close finished work, update in-progress items
|
||||||
|
4. **PUSH TO REMOTE** - This is MANDATORY:
|
||||||
|
```bash
|
||||||
|
git pull --rebase
|
||||||
|
bd sync
|
||||||
|
git push
|
||||||
|
git status # MUST show "up to date with origin"
|
||||||
|
```
|
||||||
|
5. **Clean up** - Clear stashes, prune remote branches
|
||||||
|
6. **Verify** - All changes committed AND pushed
|
||||||
|
7. **Hand off** - Provide context for next session
|
||||||
|
|
||||||
|
**CRITICAL RULES:**
|
||||||
|
- Work is NOT complete until `git push` succeeds
|
||||||
|
- NEVER stop before pushing - that leaves work stranded locally
|
||||||
|
- NEVER say "ready to push when you are" - YOU must push
|
||||||
|
- If push fails, resolve and retry until it succeeds
|
||||||
|
|
||||||
@@ -3,6 +3,10 @@
|
|||||||
This file provides guidance to Claude Code (claude.ai/code) when working with
|
This file provides guidance to Claude Code (claude.ai/code) when working with
|
||||||
code in this repository.
|
code in this repository.
|
||||||
|
|
||||||
|
Read and follow the instructions in `diachron/AGENTS.md`. That file
|
||||||
|
contains framework conventions, commands, and structure that apply to
|
||||||
|
all coding agents working on diachron-based projects.
|
||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
Diachron is an opinionated TypeScript/Node.js web framework with a Go-based
|
Diachron is an opinionated TypeScript/Node.js web framework with a Go-based
|
||||||
|
|||||||
20
DIACHRON.md
20
DIACHRON.md
@@ -88,8 +88,24 @@ There are two owners of files in a diachron project:
|
|||||||
`backend/diachron/`, and the top-level scripts (`cmd`, `develop`, `mgmt`,
|
`backend/diachron/`, and the top-level scripts (`cmd`, `develop`, `mgmt`,
|
||||||
`sync.sh`, `check.sh`).
|
`sync.sh`, `check.sh`).
|
||||||
|
|
||||||
Don't modify framework-owned files. This separation keeps framework upgrades
|
Don't modify framework-owned files unless you need to. This separation
|
||||||
clean.
|
keeps framework upgrades clean. If you do need to change framework files
|
||||||
|
(especially early on, there are rough edges), you can extract your changes
|
||||||
|
as a patch:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./diff-upstream.sh # full diff against upstream
|
||||||
|
./diff-upstream.sh --stat # just list changed files
|
||||||
|
```
|
||||||
|
|
||||||
|
This diffs every file in `file-list` against the upstream ref recorded in
|
||||||
|
`.diachron-version`.
|
||||||
|
|
||||||
|
When you do change framework files, make each change in its own commit with
|
||||||
|
a clear message explaining what the change is and why it's needed. Mixing
|
||||||
|
framework fixes with application work in a single commit makes it much
|
||||||
|
harder to upstream later. A clean history of discrete, well-explained
|
||||||
|
framework commits is the easiest thing to turn into contributions.
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,14 @@ Do not edit: master/*, logger/*, diachron/*, backend/diachron/*
|
|||||||
```
|
```
|
||||||
|
|
||||||
If a task requires framework changes, confirm with the user first.
|
If a task requires framework changes, confirm with the user first.
|
||||||
|
When framework files are modified, the changes can be extracted as a
|
||||||
|
diff against upstream with `./diff-upstream.sh` (or `--stat` to list
|
||||||
|
changed files only).
|
||||||
|
|
||||||
|
When committing framework changes, keep them in separate commits from
|
||||||
|
application code. Each framework commit should have a clear message
|
||||||
|
explaining what was changed and why. This makes it much easier to
|
||||||
|
upstream the changes later.
|
||||||
|
|
||||||
### Command safety tiers
|
### Command safety tiers
|
||||||
|
|
||||||
|
|||||||
116
diff-upstream.sh
Executable file
116
diff-upstream.sh
Executable file
@@ -0,0 +1,116 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Generate a diff of framework files against the upstream version this
|
||||||
|
# project is based on. Useful for contributing changes back to diachron.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./diff-upstream.sh # diff against .diachron-version
|
||||||
|
# ./diff-upstream.sh <ref> # diff against a specific ref
|
||||||
|
# ./diff-upstream.sh --stat # show changed files only
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
set -o pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
stat_only=false
|
||||||
|
ref=""
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "$arg" in
|
||||||
|
--stat) stat_only=true ;;
|
||||||
|
*) ref="$arg" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$ref" ]; then
|
||||||
|
if [ ! -f "$DIR/.diachron-version" ]; then
|
||||||
|
echo "Error: .diachron-version not found and no ref specified." >&2
|
||||||
|
echo "Usage: $0 [--stat] [<ref>]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
ref=$(cat "$DIR/.diachron-version")
|
||||||
|
fi
|
||||||
|
|
||||||
|
cached_repo="$HOME/.cache/diachron/v1/repositories/diachron.git"
|
||||||
|
|
||||||
|
if [ ! -d "$cached_repo" ]; then
|
||||||
|
echo "Error: cached repository not found at $cached_repo" >&2
|
||||||
|
echo "Run ./update-cached-repository.sh first." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Update cached repo
|
||||||
|
"$DIR/update-cached-repository.sh"
|
||||||
|
|
||||||
|
# Verify ref exists
|
||||||
|
if ! git -C "$cached_repo" rev-parse --verify "$ref^{commit}" >/dev/null 2>&1; then
|
||||||
|
echo "Error: ref '$ref' not found in cached repository." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Read file-list
|
||||||
|
files=()
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ "$line" =~ ^[[:space:]]*# ]] && continue
|
||||||
|
[[ -z "$line" ]] && continue
|
||||||
|
files+=("$line")
|
||||||
|
done < "$DIR/file-list"
|
||||||
|
|
||||||
|
# Check out upstream into a temp directory
|
||||||
|
tmpdir=$(mktemp -d)
|
||||||
|
cleanup() { rm -rf "$tmpdir"; }
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
git clone --quiet "$cached_repo" "$tmpdir/upstream"
|
||||||
|
git -C "$tmpdir/upstream" checkout --quiet "$ref"
|
||||||
|
|
||||||
|
# Generate diff
|
||||||
|
if $stat_only; then
|
||||||
|
diff -rq "$tmpdir/upstream" "$DIR" \
|
||||||
|
--no-dereference \
|
||||||
|
2>/dev/null \
|
||||||
|
| grep -v '^\.' \
|
||||||
|
|| true
|
||||||
|
|
||||||
|
# Simpler: just list files that differ
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
# Skip directories
|
||||||
|
[ -d "$DIR/$f" ] && continue
|
||||||
|
|
||||||
|
upstream="$tmpdir/upstream/$f"
|
||||||
|
local="$DIR/$f"
|
||||||
|
|
||||||
|
if [ ! -f "$upstream" ] && [ -f "$local" ]; then
|
||||||
|
echo "added: $f"
|
||||||
|
elif [ -f "$upstream" ] && [ ! -f "$local" ]; then
|
||||||
|
echo "removed: $f"
|
||||||
|
elif [ -f "$upstream" ] && [ -f "$local" ]; then
|
||||||
|
if ! diff -q "$upstream" "$local" >/dev/null 2>&1; then
|
||||||
|
echo "modified: $f"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
[ -d "$DIR/$f" ] && continue
|
||||||
|
|
||||||
|
upstream="$tmpdir/upstream/$f"
|
||||||
|
local="$DIR/$f"
|
||||||
|
|
||||||
|
if [ ! -f "$upstream" ] && [ -f "$local" ]; then
|
||||||
|
diff -u /dev/null "$local" \
|
||||||
|
--label "a/$f" --label "b/$f" \
|
||||||
|
|| true
|
||||||
|
elif [ -f "$upstream" ] && [ ! -f "$local" ]; then
|
||||||
|
diff -u "$upstream" /dev/null \
|
||||||
|
--label "a/$f" --label "b/$f" \
|
||||||
|
|| true
|
||||||
|
elif [ -f "$upstream" ] && [ -f "$local" ]; then
|
||||||
|
diff -u "$upstream" "$local" \
|
||||||
|
--label "a/$f" --label "b/$f" \
|
||||||
|
|| true
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
Reference in New Issue
Block a user