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
7 changes: 7 additions & 0 deletions .rabbit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Rabbit Context

This directory keeps Rabbit-facing repo context and generated `dev.kit` evidence.

- `context.yaml` is generated by `dev.kit repo`; do not edit it manually.
- Keep human-authored Rabbit CI notes, delivery entry points, and repo-specific workflow guidance in this README.
- After changing repo docs, manifests, scripts, or workflows, run `dev.kit repo` to refresh generated context.
4 changes: 2 additions & 2 deletions .rabbit/context.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ version: udx.dev/dev.kit/v1
generator:
tool: dev.kit
repo: https://github.com/udx/dev.kit
version: 0.20.0
generated_at: 2026-07-08T15:15:15Z
version: 0.20.1
generated_at: 2026-07-10T09:48:47Z
sources:
homepage: https://udx.dev/kit
repository: https://github.com/udx/dev.kit
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

<https://udx.dev/kit>

`dev.kit` turns repositories into self-explaining repo contracts for humans, scripts, and CI/CD.
`dev.kit` provides repo context coverage for every handoff.

It reads repo-owned docs, manifests, workflows, commands, dependencies, and gaps, then writes `.rabbit/context.yaml` so humans, agents, scripts, and CI/CD systems such as Rabbit CI can work from the same declared contract.

It helps teams and repositories:

1. understand how the repo actually works
2. keep repo standards, manifests, refs, and dependency contracts traceable
3. regenerate reliable context from repo signals instead of tribal knowledge
3. regenerate reliable handoff context from repo signals instead of tribal knowledge

The model is:

Expand Down
5 changes: 5 additions & 0 deletions changes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changes

### 0.20.1

- Keep declared root YAML contract discovery aligned with repo file filtering so gitignored local/private YAML is not promoted into generated context.
- Seed missing `.rabbit/README.md` files so repos initialized by `dev.kit repo` have a clear Rabbit-facing notes surface without adding a generic `docs/README.md` stub.
Comment thread
fqjony marked this conversation as resolved.

Comment thread
fqjony marked this conversation as resolved.
### 0.20.0

- Discover root YAML config contracts from explicit top-level `contract` / `contracts` metadata or typed `kind` + `version` manifests instead of filename-specific allowlists.
Expand Down
2 changes: 1 addition & 1 deletion docs/how-it-works.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# How It Works

`dev.kit` turns repo-declared structure into a working repo contract.
`dev.kit` turns repo-declared structure into context coverage for repo handoffs.

The default starting point is:

Expand Down
23 changes: 22 additions & 1 deletion lib/modules/repo_scaffold.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ This repository uses \`dev.kit\` for repo-driven context coverage.

- Run \`dev.kit\` to inspect environment and repo context status
- Run \`dev.kit repo\` to regenerate \`.rabbit/context.yaml\`
"

dev_kit_repo_write_if_missing "${repo_root}/.rabbit/README.md" "# Rabbit Context

This directory keeps Rabbit-facing repo context and generated \`dev.kit\` evidence.

- \`context.yaml\` is generated by \`dev.kit repo\`; do not edit it manually.
- Keep human-authored Rabbit CI notes, delivery entry points, and repo-specific workflow guidance in this README.
- After changing repo docs, manifests, scripts, or workflows, run \`dev.kit repo\` to refresh generated context.
"

dev_kit_repo_write_if_missing "${repo_root}/.github/dependabot.yml" "version: 2
Expand Down Expand Up @@ -293,9 +302,21 @@ EOF

dev_kit_repo_declared_root_contract_manifest_files() {
local repo_root="$1"
local candidate_files=""
local manifest_path=""
local manifest_rel=""

if dev_kit_sync_has_git_repo "$repo_root"; then
candidate_files="$(
(
cd "$repo_root" &&
git ls-files -z --cached --others --exclude-standard -- '*.yaml' '*.yml' 2>/dev/null
) | tr '\0' '\n' | awk -v repo_root="$repo_root" 'NF && $0 !~ /\// && $0 !~ /^\./ { printf "%s/%s\n", repo_root, $0 }' | sort
)"
else
candidate_files="$(find "$repo_root" -maxdepth 1 -type f \( -name '*.yaml' -o -name '*.yml' \) 2>/dev/null | sort)"
fi

while IFS= read -r manifest_path; do
[ -f "$manifest_path" ] || continue
manifest_rel="${manifest_path#"${repo_root}/"}"
Expand All @@ -310,7 +331,7 @@ dev_kit_repo_declared_root_contract_manifest_files() {
printf '%s\n' "$manifest_rel"
fi
done <<EOF
$(find "$repo_root" -maxdepth 1 -type f \( -name '*.yaml' -o -name '*.yml' \) 2>/dev/null | sort)
$candidate_files
EOF
}

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@udx/dev-kit",
"version": "0.20.0",
"version": "0.20.1",
"description": "Context-driven engineering toolkit for AI agents and developers",
"license": "MIT",
"repository": {
Expand Down
42 changes: 39 additions & 3 deletions tests/suite.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@ DOCUMENTED_SHELL_REPO="$REPO_DIR/tests/fixtures/documented-shell-repo"
DOCKER_REPO="$REPO_DIR/tests/fixtures/docker-repo"
SIMPLE_ACTION_REPO="$TEST_HOME/simple-action-repo"
HOME_ACTION_REPO="$TEST_HOME/home-action-repo"
DOCUMENTED_SHELL_ACTION_REPO="$TEST_HOME/documented-shell-action-repo"
DOCKER_ACTION_REPO="$TEST_HOME/docker-action-repo"
EMPTY_REPO="$TEST_HOME/empty-repo"
IGNORED_ACTION_REPO="$TEST_HOME/ignored-action-repo"
WORKFLOW_CONTRACT_REPO="$TEST_HOME/workflow-contract-repo"
DECLARED_CONFIG_REPO="$TEST_HOME/declared-config-repo"
REFERENCE_DOC_COMMAND_REPO="$TEST_HOME/reference-doc-command-repo"
PRESERVED_RABBIT_REPO="$TEST_HOME/preserved-rabbit-repo"
AVAILABLE_TEST_GROUPS="core repo-contract"
TEST_ONLY="${DEV_KIT_TEST_ONLY:-}"

Expand Down Expand Up @@ -115,6 +117,9 @@ setup_declared_config_repo() {
# Declared Config Repo

Runtime variables are declared in `work-conf.yaml`.
EOF
cat > "$repo_dir/.gitignore" <<'EOF'
local-private.yaml
EOF
cat > "$repo_dir/work-conf.yaml" <<'EOF'
---
Expand All @@ -134,6 +139,13 @@ contract:
purpose: local automation interface notes
refs:
- README.md
EOF
cat > "$repo_dir/local-private.yaml" <<'EOF'
---
kind: localPrivateConfig
version: example.dev/private-v1/config
config:
env: {}
EOF
cat > "$repo_dir/source-notes.yaml" <<'EOF'
# Source notes with references are useful context, but not a manifest contract.
Expand Down Expand Up @@ -235,6 +247,7 @@ if should_run_explicit "repo-contract"; then
declared_config_dependencies="$(awk '/^dependencies:/{flag=1;next} /^# /{if(flag) exit} flag{print}' "$declared_config_context_yaml")"
assert_contains "$declared_config_dependencies" "repo: example/runtime" "repo contract: traces declared root YAML manifest owner as dependency"
assert_not_contains "$(cat "$declared_config_context_yaml")" "path: source-notes.yaml" "repo contract: does not promote source comments alone to manifest"
assert_not_contains "$(cat "$declared_config_context_yaml")" "path: local-private.yaml" "repo contract: excludes gitignored root YAML contracts"
fi

if should_run "core"; then
Expand Down Expand Up @@ -382,7 +395,9 @@ if should_run "core"; then
assert_contains "$env_json" "\"command\": \"env\"" "env: reports command name"
assert_contains "$env_json" "\"workflow\": {" "env: reports workflow contract"

repo_json="$(cd "$DOCUMENTED_SHELL_REPO" && dev.kit repo --json)"
cp -R "$DOCUMENTED_SHELL_REPO" "$DOCUMENTED_SHELL_ACTION_REPO"

repo_json="$(cd "$DOCUMENTED_SHELL_ACTION_REPO" && dev.kit repo --json)"
assert_contains "$repo_json" "\"archetype\":" "repo: reports archetype"
assert_contains "$repo_json" "\"context\":" "repo: reports context path"
assert_contains "$repo_json" "\"context_status\": \"current\"" "repo: reports current workflow context after write"
Expand All @@ -391,7 +406,7 @@ if should_run "core"; then
assert_contains "$repo_json" "\"id\": \"confirm-research-fix-loop\"" "repo: includes confirmation loop action"
assert_contains "$repo_json" "\"workflow\": {" "repo: reports workflow contract"

repo_text="$(cd "$DOCUMENTED_SHELL_REPO" && dev.kit repo)"
repo_text="$(cd "$DOCUMENTED_SHELL_ACTION_REPO" && dev.kit repo)"
assert_contains "$repo_text" "[workflow]" "repo text: renders workflow section"
assert_contains "$repo_text" "[read first]" "repo text: renders read first section"
assert_contains "$repo_text" "[factors]" "repo text: renders factors section"
Expand All @@ -407,7 +422,7 @@ if should_run "core"; then
printf 'boom\n' >&2
return 42
}
dev_kit_cmd_repo text "$DOCUMENTED_SHELL_REPO" 2>&1
dev_kit_cmd_repo text "$DOCUMENTED_SHELL_ACTION_REPO" 2>&1
)"
repo_write_failure_status=$?
set -e
Expand Down Expand Up @@ -504,6 +519,7 @@ EOF
declared_config_dependencies="$(awk '/^dependencies:/{flag=1;next} /^# /{if(flag) exit} flag{print}' "$declared_config_context_yaml")"
assert_contains "$declared_config_dependencies" "repo: example/runtime" "declared config repo: traces explicit root YAML manifest owner as dependency"
assert_not_contains "$(cat "$declared_config_context_yaml")" "path: source-notes.yaml" "declared config repo: does not promote source comments alone to manifest"
assert_not_contains "$(cat "$declared_config_context_yaml")" "path: local-private.yaml" "declared config repo: excludes gitignored root YAML contracts"

mkdir -p "$WORKFLOW_CONTRACT_REPO/.github/workflows"
git -C "$WORKFLOW_CONTRACT_REPO" init >/dev/null 2>&1
Expand Down Expand Up @@ -558,6 +574,22 @@ EOF
assert_not_contains "$(cat "$reference_doc_context_yaml")" "run: make build" "reference docs repo: ignores reference-only build example"
assert_not_contains "$(cat "$reference_doc_context_yaml")" "run: make run" "reference docs repo: ignores reference-only run example"

mkdir -p "$PRESERVED_RABBIT_REPO/.rabbit" "$PRESERVED_RABBIT_REPO/docs"
git -C "$PRESERVED_RABBIT_REPO" init >/dev/null 2>&1
cat > "$PRESERVED_RABBIT_REPO/README.md" <<'EOF'
# Preserved Rabbit Docs Repo
EOF
cat > "$PRESERVED_RABBIT_REPO/.rabbit/README.md" <<'EOF'
# Existing Rabbit Notes

Keep this repo-specific Rabbit CI guidance.
EOF
preserved_rabbit_json="$(cd "$PRESERVED_RABBIT_REPO" && dev.kit repo --json)"
assert_contains "$preserved_rabbit_json" "\"context\":" "preserved rabbit repo: reports context path"
assert_contains "$(cat "$PRESERVED_RABBIT_REPO/.rabbit/README.md")" "Existing Rabbit Notes" "preserved rabbit repo: keeps existing rabbit README"
assert_not_contains "$(cat "$PRESERVED_RABBIT_REPO/.rabbit/README.md")" "This directory keeps Rabbit-facing repo context" "preserved rabbit repo: does not overwrite rabbit README"
assert_file_missing "$PRESERVED_RABBIT_REPO/docs/README.md" "preserved rabbit repo: does not create generic docs README"

mkdir -p "$EMPTY_REPO"
git -C "$EMPTY_REPO" init >/dev/null 2>&1

Expand All @@ -573,11 +605,15 @@ EOF

assert_file_exists "$EMPTY_REPO/README.md" "empty repo: creates README"
assert_file_exists "$EMPTY_REPO/docs" "empty repo: creates docs dir"
assert_file_missing "$EMPTY_REPO/docs/README.md" "empty repo: does not create generic docs README"
assert_file_exists "$EMPTY_REPO/.rabbit" "empty repo: creates rabbit dir"
assert_file_exists "$EMPTY_REPO/.rabbit/README.md" "empty repo: creates rabbit README"
assert_file_exists "$EMPTY_REPO/.github/workflows" "empty repo: creates workflows dir"
assert_file_exists "$EMPTY_REPO/.github/dependabot.yml" "empty repo: creates dependabot config"
assert_contains "$(cat "$EMPTY_REPO/.github/dependabot.yml")" "package-ecosystem: github-actions" "empty repo: dependabot targets github actions"
assert_contains "$(cat "$EMPTY_REPO/README.md")" "This repository uses \`dev.kit\`" "empty repo: seeds README"
assert_contains "$(cat "$EMPTY_REPO/.rabbit/README.md")" "Rabbit-facing repo context" "empty repo: seeds rabbit README"
assert_contains "$(cat "$EMPTY_REPO/.rabbit/README.md")" "\`context.yaml\` is generated by \`dev.kit repo\`" "empty repo: explains generated context"
fi

printf "ok - dev.kit suite completed\n"