From 3bc73ea070a8cbc9a1cc17b5d5c6f5de7870066c Mon Sep 17 00:00:00 2001 From: Dmitry Smirnov Date: Tue, 21 Apr 2026 11:06:17 +0300 Subject: [PATCH 01/12] Simplify dev.kit flow and docs --- .rabbit/context.yaml | 19 +- AGENTS.md | 56 ++-- README.md | 151 +++-------- README_old.md | 155 +++++++++++ bin/dev-kit | 84 +++--- config/env.yaml | 6 + docs/agents.md | 167 ------------ docs/context-coverage.md | 61 +++++ docs/context.md | 141 ---------- docs/environment-config.md | 67 +++++ docs/experience-guidance.md | 52 ++++ docs/how-it-works.md | 62 +++++ docs/installation.md | 14 +- docs/integration.md | 120 --------- docs/smart-dependency-detection.md | 41 +++ lib/commands/agent.sh | 71 ++---- lib/commands/env.sh | 80 ++++++ lib/commands/learn.sh | 4 +- lib/commands/repo.sh | 3 +- lib/modules/bootstrap.sh | 2 +- lib/modules/config_catalog.sh | 172 +------------ lib/modules/dev_sync.sh | 56 +++- lib/modules/learning_sources.sh | 19 ++ lib/modules/local_env.sh | 93 +++++++ lib/modules/repo_archetypes.sh | 63 +---- lib/modules/repo_navigation.sh | 2 +- lib/modules/repo_reports.sh | 3 +- lib/modules/repo_scaffold.sh | 3 +- lib/modules/repo_signals.sh | 5 + src/configs/archetype-signals.yaml | 35 --- .../{archetype-rules.yaml => archetypes.yaml} | 3 +- src/configs/context-config.yaml | 16 +- src/configs/detection-patterns.yaml | 2 + src/configs/detection-signals.yaml | 19 ++ src/configs/development-practices.yaml | 47 ---- src/configs/development-workflows.yaml | 138 ---------- src/configs/github-issues.yaml | 159 ------------ src/configs/github-prs.yaml | 241 ------------------ src/configs/knowledge-base.yaml | 36 --- src/configs/repo-scaffold.yaml | 75 ------ ...019d4f54-eddc-7350-a757-3bb578d24f99.jsonl | 10 - .../kubernetes-repo/k8s/deployment.yaml | 6 + tests/fixtures/php-repo/composer.json | 6 - tests/fixtures/php-repo/phpunit.xml | 8 - tests/fixtures/php-repo/tests/ExampleTest.php | 5 - .../.github/workflows/reusable-check.yml | 20 -- tests/fixtures/workflow-repo/README.md | 19 -- tests/suite.sh | 50 +++- tests/worker-smoke.sh | 154 +++++++++++ 49 files changed, 1094 insertions(+), 1727 deletions(-) create mode 100644 README_old.md create mode 100644 config/env.yaml delete mode 100644 docs/agents.md create mode 100644 docs/context-coverage.md delete mode 100644 docs/context.md create mode 100644 docs/environment-config.md create mode 100644 docs/experience-guidance.md create mode 100644 docs/how-it-works.md delete mode 100644 docs/integration.md create mode 100644 docs/smart-dependency-detection.md create mode 100644 lib/commands/env.sh delete mode 100644 src/configs/archetype-signals.yaml rename src/configs/{archetype-rules.yaml => archetypes.yaml} (93%) delete mode 100644 src/configs/development-practices.yaml delete mode 100644 src/configs/development-workflows.yaml delete mode 100644 src/configs/github-issues.yaml delete mode 100644 src/configs/github-prs.yaml delete mode 100644 src/configs/knowledge-base.yaml delete mode 100644 src/configs/repo-scaffold.yaml delete mode 100644 tests/fixtures/codex-home/sessions/2026/04/02/rollout-2026-04-02T20-54-19-019d4f54-eddc-7350-a757-3bb578d24f99.jsonl create mode 100644 tests/fixtures/kubernetes-repo/k8s/deployment.yaml delete mode 100644 tests/fixtures/php-repo/composer.json delete mode 100644 tests/fixtures/php-repo/phpunit.xml delete mode 100644 tests/fixtures/php-repo/tests/ExampleTest.php delete mode 100644 tests/fixtures/workflow-repo/.github/workflows/reusable-check.yml delete mode 100644 tests/fixtures/workflow-repo/README.md create mode 100755 tests/worker-smoke.sh diff --git a/.rabbit/context.yaml b/.rabbit/context.yaml index 972cd34..fe9a533 100644 --- a/.rabbit/context.yaml +++ b/.rabbit/context.yaml @@ -2,7 +2,7 @@ # Run `dev.kit repo` to refresh. kind: repoContext version: udx.io/dev.kit/v1 -generated: 2026-04-17 +generated: 2026-04-21 repo: name: dev.kit @@ -12,9 +12,11 @@ repo: refs: - ./README.md - ./docs/installation.md - - ./docs/context.md - - ./docs/agents.md - - ./docs/integration.md + - ./docs/how-it-works.md + - ./docs/environment-config.md + - ./docs/context-coverage.md + - ./docs/experience-guidance.md + - ./docs/smart-dependency-detection.md - ./docs - ./.rabbit - ./.github/workflows @@ -50,19 +52,12 @@ dependencies: # Config manifests — traceable workflow and tooling dependencies # Read these to understand what controls repo behavior before reading shell code. manifests: - - src/configs/archetype-rules.yaml — archetype definitions and matching rules - - src/configs/archetype-signals.yaml — file/dir signals for framework and platform detection + - src/configs/archetypes.yaml — repo archetype definitions and matching rules - src/configs/audit-rules.yaml — factor gap messages and improvement guidance - src/configs/context-config.yaml — repo root markers and priority paths - src/configs/detection-patterns.yaml — regex patterns for build/verify/run command detection - src/configs/detection-signals.yaml — file/dir/glob patterns for factor analysis - - src/configs/development-practices.yaml — engineering principles inlined into repo context - - src/configs/development-workflows.yaml — git workflow steps, PR process, and operational notes - - src/configs/github-issues.yaml — issue templates, labels, and agent issue workflow - - src/configs/github-prs.yaml — PR templates, bot reviewers, and post-merge checklist - - src/configs/knowledge-base.yaml — org hierarchy and preferred knowledge sources - src/configs/learning-workflows.yaml — agent session discovery and lesson extraction rules - - src/configs/repo-scaffold.yaml — baseline dirs/files per archetype and factor - .github/workflows/context7-ops.yml - .github/workflows/npm-release-ops.yml - deploy.yml diff --git a/AGENTS.md b/AGENTS.md index 325e68c..76812b0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -57,25 +57,13 @@ Prior session lessons — read before starting work: ## Workflow -The dev.kit lifecycle: **repo → agent → work → PR → merge**. Follow these steps in order. Use them as repo-declared defaults when live GitHub context does not provide a more specific current signal. Steps with notes contain operational guidance. - - - Refresh repo context: Run `dev.kit` → `dev.kit repo` → `dev.kit agent` before starting work. Each command guides to the next required step. This resyncs repo context, environment state, and the AGENTS.md execution contract. A current context.yaml is the source of truth for refs, commands, gaps, and lessons. Do not rely on ad hoc prompt memory when the repo contract can be read from disk. When GitHub context is available, prefer current issues, pull requests, review state, and commit history over stale memory or generic workflow defaults. - - Read linked GitHub issue and confirm scope: If a GitHub issue URL is available, read the full body and comments, confirm the repo matches the issue scope, and map acceptance criteria before writing any code. Use the issue URL as the cross-repo context root. - - Reuse GitHub repo patterns: Before creating a branch, PR, issue, or status update, inspect the repo's recent GitHub history and reuse its established naming and writing patterns. Treat existing branch names, PR titles and bodies, issue templates, and close-out comments as the default style guide. - - Inspect git status - - Analyze local changes - - Analyze branch state - - Group logical commits - - Bump version and changelog if supported - - Create or validate feature branch - - Push branch to remote - - Generate pull request description: Pick the PR template type from src/configs/github-prs.yaml (feature, deployment, ops, hotfix). Fill every required section. Include "Closes #N" for linked issues. Add a "Backlog from this investigation" section for any new gaps found. Use github-prs.yaml and current GitHub PR/body patterns in this repo as the base guidance. - - Create pull request - - Monitor related workflow executions: After PR creation, monitor the related GitHub workflow runs and status checks. Open the run details when needed, watch for failed or stuck jobs, and treat GitHub workflow execution as the primary verification path when the repo already has CI coverage. - - Loop automated review feedback: After PR creation, wait for Copilot, Devin, and CodeQL reviews. Read each review from github-prs.yaml bot guidance. Address actionable findings with code changes, reply to each bot comment, and resolve the thread when handled. Repeat this loop after each push until bot feedback is clean. Do not request human review while bot findings are unaddressed. - - Verify required status checks: All required checks must pass before requesting human review. For infra PRs, open check details and review the Terraform plan output. For CodeQL, review findings in the Security tab. When the repo already has GitHub workflow coverage, prefer those executions as the primary verification path and monitor them closely. Use local verification to reproduce failures or cover gaps, not as a universal gate. - - Post close-out comment on linked issue: After PR is created, post a brief comment on the linked issue with the PR URL, what changed, and any follow-up items. GitHub auto-closes the issue on merge when "Closes #N" is in the PR body — do not close manually. - - Post-merge close-out and backlog: After merge: verify issue auto-closed, post close-out comment, open issues for any backlog items from the PR, verify monitoring changes are live. See post_merge steps in github-prs.yaml. +Use these repo-derived steps as the default operating path. Adapt them to the current agent role instead of forcing a single development lifecycle onto every task. + + - Read the highest-priority repo refs first: ./README.md, ./docs/installation.md, ./docs/how-it-works.md, ./docs/environment-config.md, ./docs/context-coverage.md, ./docs/experience-guidance.md, ./docs/smart-dependency-detection.md, ./docs, ./.rabbit, ./.github/workflows, ./Makefile, ./package.json, ./deploy.yml, ./lib, ./src, ./tests + - Run the canonical verification command: make test + - Run the canonical build command when needed: make build + - Use the canonical runtime command instead of ad hoc startup paths: make run + - Review lessons-learned and follow-up outputs after changes stabilize: dev.kit learn ### Learned from prior sessions @@ -105,28 +93,16 @@ Patterns detected from agent sessions on this repo. Follow these in addition to - `Legacy reduction`: when a new direction is accepted, archive or delete conflicting old modules/configs instead of carrying both models forward. - `Config-over-code`: express repo rules in YAML/manifests first, then keep shell glue thin and composable. - `Agent handoff`: refresh repo context, manifest, and AGENTS instructions before deeper agent work so the repo contract is the source of truth. +- `Docs-first alignment`: review README, docs, and tests before refactoring, restate the target workflow, then simplify code and remove mismatched legacy paths. +- `Workflow tracing`: locate the actual workflow or deploy file first, then trace the commands and supporting docs that drive execution. +- `Verification scope`: run the smallest local check that proves the current change, defer heavyweight coverage to CI, and call the tradeoff out explicitly. +- `Legacy reduction`: when a new direction is accepted, archive or delete conflicting old modules/configs instead of carrying both models forward. +- `Agent handoff`: refresh repo context, manifests, and AGENTS.md before deeper agent work so the repo contract is the source of truth. ## Engineering practices - - Keep the repository as the primary source of truth so context-driven engineering comes from repo contracts, docs, tests, config, and repo-native notes instead of agent memory. - - Prefer repo-centric mechanisms that discover workflows, tools, formats, and refs dynamically instead of hardcoding per-agent assumptions. - - Keep markdown, yaml, diagrams, tests, and command contracts self-contained in the repo so local and remote UDX workflows stay aligned. - - Keep deterministic workflow logic in repo config and scripts, and reserve AI agents for reading that contract, generating grounded summaries, and handling non-deterministic judgment without inventing hidden rules. - - Operate from repo-declared context at all times. Do not carry assumptions across sessions or rely on prompt history when the repo contract is available on disk. - - After loading the repo contract, prefer current GitHub issues, pull requests, review state, and commit history as the primary dynamic source for agent decisions. Use repo workflow and practice catalogs as fallback defaults when live GitHub signal is missing or thin. - - Reuse the repo's current GitHub patterns for branch names, PR titles and descriptions, issue writeups, and follow-up comments instead of inventing a new style for each change. - - When understanding behavior, read the YAML manifest that defines it before reading the code that implements it. Manifests are the interface — code is the mechanism. - - Check existing org patterns, configs, workflows, and templates before creating new ones. Reuse declared patterns instead of inventing alternatives. - - Detect the repo's canonical verification surface from context, but prefer GitHub workflow executions and monitor their outcomes when the repo already has CI coverage. Use local verification for quick scoped debugging, missing CI coverage, or reproducing workflow failures. - - After a PR exists, read automated review feedback, fix actionable findings, reply to false positives, resolve threads, and repeat until workflow state and bot feedback are clean. - - Keep the delivery chain explicit — branch, PR, and issue must be connected before close-out. Do not treat any step as done until the link to the next step is visible. - - Report outcomes with exact URLs, versions, findings deltas, and next steps so follow-up can be reused by humans and agents without drift. - - Use README, docs, and tests as the first alignment surface before broad refactors. Read the declared workflow before changing the implementation. - - Do not require custom repo files for dev.kit to work. Prefer standard engineering signals such as README, docs, tests, manifests, workflows, and deployment config, with dev.kit-owned continuity treated as optional acceleration only. - - Express repo rules in YAML manifests first, then keep shell glue thin and composable. Policy belongs in config, not buried in imperative scripts. - - When a new direction is accepted, archive or delete conflicting old modules and configs instead of carrying both models forward. - - If local verification is needed, run the smallest local check that proves the current change. Prefer broader or slower coverage in GitHub workflows, monitor the workflow run, and call the tradeoff out explicitly. - - Make sure to develop and test incrementally, so it is easier to detect problems early and build on verified behavior. - - Make sure to protect development executions with scoped and limited tasks, so failures are easier to isolate and blast radius stays low. - - Use the linked GitHub issue as the cross-repo context root. When work spans multiple repos, the issue URL anchors scope, acceptance criteria, and follow-up across all of them. + - Start from `.rabbit/context.yaml`, then read only the highest-priority repo refs it points to. + - Prefer repo-declared commands, manifests, workflows, and tests over ad hoc exploration. + - Treat current GitHub state as useful live context when available, not as a mandatory workflow for every task. + - Keep generated guidance lightweight. Do not duplicate repo context already serialized in `.rabbit/context.yaml`. diff --git a/README.md b/README.md index 3a129d1..50bb6c8 100644 --- a/README.md +++ b/README.md @@ -2,101 +2,34 @@ -**GitHub-first session flow for developers and AI agents.** +**Repository context coverage for coding agents.** -dev.kit separates three concerns: +`dev.kit` turns repository knowledge into a working contract for agents. It helps an agent start from what the repo already declares, then continue from current repo and GitHub context instead of guessing. -- base repo context signals -- deterministic tracing and mapping -- agent execution behavior - -It generates `.rabbit/context.yaml` as the structured repo contract, then generates `AGENTS.md` as a built execution artifact that tells agents how to use that context with current GitHub experience first, and repo-declared workflow defaults when GitHub does not provide enough signal. - -In practice, dev.kit is middleware between repo facts and live GitHub experience. It keeps each work session anchored to the repo contract, then pushes developers and agents to use current issues, pull requests, review threads, workflow runs, and prior repo patterns before inventing new approaches. +The goal is straightforward: detect repo context, serialize it into `.rabbit/context.yaml`, and generate `AGENTS.md` that stays aligned with that context. ```bash npm install -g @udx/dev-kit ``` ---- - -## How it works - -``` -dev.kit → dev.kit repo → dev.kit agent -───────────────── ────────────────── ────────────────── -check environment analyze repo generate AGENTS.md -detect archetype trace dependencies write execution contract -guide to next write context.yaml from context.yaml -``` - -Each command moves the session forward and tells the next actor what to do. Agents should rerun the flow at each new interaction or session so context, workflow, and repo state stay synced. - ---- - ## Quick start ```bash cd my-repo -dev.kit # check tools, detect repo -dev.kit repo # analyze factors, trace deps, write .rabbit/context.yaml -dev.kit agent # generate AGENTS.md execution contract -``` - -The intended operating loop is: - -1. install `dev.kit` -2. start work with `dev.kit`, `dev.kit repo`, and `dev.kit agent` -3. read `.rabbit/context.yaml` and `AGENTS.md` -4. do the actual implementation using current GitHub repo experience first -5. resync the same flow at the next interaction or after repo changes - ---- - -## Generated Context And Workflow - -**`.rabbit/context.yaml`** — generated repo map from repo definitions, source files, detected commands, traced dependencies, gaps, and other serializable repo signals: - -```yaml -repo: - name: dev.kit - archetype: library-cli - profile: node - -refs: - - ./README.md - - ./package.json - -commands: - verify: make test - build: make build - -dependencies: - - repo: udx/reusable-workflows - type: reusable workflow - resolved: true - archetype: workflow-repo - used_by: - - .github/workflows/npm-release-ops.yml - -gaps: - - config (partial) +dev.kit # full guided refresh: env + repo context + AGENTS.md +dev.kit env # inspect tools, auth state, and env config +dev.kit env --config +dev.kit repo # refresh only .rabbit/context.yaml +dev.kit agent # refresh only AGENTS.md ``` -**`AGENTS.md`** — generated execution artifact for agents. It should stay simpler than `context.yaml`: rules, workflow, verification, and how to use current GitHub and learned context without duplicating refs, manifests, or dependency maps already serialized in `context.yaml`. - -Together, these two artifacts create a disciplined loop: - -- `context.yaml` says what the repo declares and what dev.kit could trace -- `AGENTS.md` says how to act on that contract using live GitHub experience first - ---- - ## Commands | Command | What it does | |---------|-------------| -| `dev.kit` | Check environment, detect repo, show next step | +| `dev.kit` | Happy path: check environment, refresh repo context, generate `AGENTS.md` | +| `dev.kit env` | Inspect environment tools, auth state, and env config | +| `dev.kit env --config` | Create or update local env config for disabling tools or credentials | | `dev.kit repo` | Analyze factors, trace dependencies, pull GitHub signals, write `context.yaml` | | `dev.kit repo --force` | Re-resolve all dependencies from scratch | | `dev.kit agent` | Generate `AGENTS.md` from `context.yaml` | @@ -104,35 +37,6 @@ Together, these two artifacts create a disciplined loop: All commands support `--json` for machine-readable output. ---- - -## Repo Context - -Repo context comes from repo source first: README, docs, workflows, manifests, tests, and other declared refs. `dev.kit repo` then traces and maps dependencies, commands, gaps, and other serializable signals into `context.yaml`. `AGENTS.md` turns that repo map into an operating contract for agents, using current GitHub context as the primary dynamic input and repo workflow/practice catalogs as fallback defaults. - -That means dev.kit does not just tell an agent what files exist. It also pushes the session toward the repo's real delivery loop: branch naming based on repo history, issue and PR writing based on existing patterns, bot feedback loops, and workflow status checks before close-out. - -## Cross-repo tracing - -Traces dependencies from 6 sources: workflow reuse, GitHub actions, Docker images, versioned YAML, GitHub URLs, npm packages. - -Same-org repos resolved via `gh api` + sibling directory. Docker images mapped to source repos automatically. - -```yaml -# udx/rabbit-automation-action -dependencies: - - repo: udx/gh-workflows - type: reusable workflow - resolved: true - - - repo: usabilitydynamics/udx-worker-tooling:0.19.0 - type: base image - resolved: true - source_repo: udx/worker-tooling -``` - ---- - ## Install ```bash @@ -145,11 +49,34 @@ curl -fsSL https://raw.githubusercontent.com/udx/dev.kit/latest/bin/scripts/inst Use one install path at a time. Installing with npm removes the curl-managed `~/.udx/dev.kit` home and shim. Installing with curl removes the global `@udx/dev-kit` package before laying down the local shim and home directory. ---- - ## Docs +- [How It Works](docs/how-it-works.md) — the happy path, artifacts, and command roles +- [Environment Config](docs/environment-config.md) — `dev.kit env`, `env.yaml`, and capability control +- [Context Coverage](docs/context-coverage.md) — what `context.yaml` covers, what gaps mean, and what is intentionally excluded +- [Experience Guidance](docs/experience-guidance.md) — how `AGENTS.md` is generated and how live repo experience shapes guidance +- [Smart Dependency Detection](docs/smart-dependency-detection.md) — cross-repo tracing sources and resolution model - [Installation](docs/installation.md) — npm and curl installs, cleanup, uninstall, and verification -- [Context](docs/context.md) — `.rabbit/context.yaml`, its sections, and how it is generated -- [Agents](docs/agents.md) — `AGENTS.md` generation and how agents use it -- [Integration](docs/integration.md) — how the CLI, repo context, and agent workflow fit together + +## Testing + +For fast local checks, the repo still includes a shell test suite: + +```bash +bash tests/suite.sh --only core +``` + +For installed-CLI testing in a real worker environment, use the published worker image: + +```bash +bash tests/worker-smoke.sh +``` + +That runner: + +- installs the current repo with `npm install -g /workspace` +- runs the installed `dev.kit` inside `usabilitydynamics/udx-worker:latest` +- mounts a target repo so `dev.kit` can be exercised against real local repos +- copies the target repo into scratch space by default so repo context can be intentionally broken without touching the original checkout +- supports `DEV_KIT_TEST_DISABLED_TOOLS` and `DEV_KIT_TEST_DISABLED_CREDS` for env-config scenarios +- supports `DEV_KIT_TEST_PREPARE_CMD` for lightweight repo mutation before running `dev.kit` diff --git a/README_old.md b/README_old.md new file mode 100644 index 0000000..3a129d1 --- /dev/null +++ b/README_old.md @@ -0,0 +1,155 @@ +# dev.kit + + + +**GitHub-first session flow for developers and AI agents.** + +dev.kit separates three concerns: + +- base repo context signals +- deterministic tracing and mapping +- agent execution behavior + +It generates `.rabbit/context.yaml` as the structured repo contract, then generates `AGENTS.md` as a built execution artifact that tells agents how to use that context with current GitHub experience first, and repo-declared workflow defaults when GitHub does not provide enough signal. + +In practice, dev.kit is middleware between repo facts and live GitHub experience. It keeps each work session anchored to the repo contract, then pushes developers and agents to use current issues, pull requests, review threads, workflow runs, and prior repo patterns before inventing new approaches. + +```bash +npm install -g @udx/dev-kit +``` + +--- + +## How it works + +``` +dev.kit → dev.kit repo → dev.kit agent +───────────────── ────────────────── ────────────────── +check environment analyze repo generate AGENTS.md +detect archetype trace dependencies write execution contract +guide to next write context.yaml from context.yaml +``` + +Each command moves the session forward and tells the next actor what to do. Agents should rerun the flow at each new interaction or session so context, workflow, and repo state stay synced. + +--- + +## Quick start + +```bash +cd my-repo +dev.kit # check tools, detect repo +dev.kit repo # analyze factors, trace deps, write .rabbit/context.yaml +dev.kit agent # generate AGENTS.md execution contract +``` + +The intended operating loop is: + +1. install `dev.kit` +2. start work with `dev.kit`, `dev.kit repo`, and `dev.kit agent` +3. read `.rabbit/context.yaml` and `AGENTS.md` +4. do the actual implementation using current GitHub repo experience first +5. resync the same flow at the next interaction or after repo changes + +--- + +## Generated Context And Workflow + +**`.rabbit/context.yaml`** — generated repo map from repo definitions, source files, detected commands, traced dependencies, gaps, and other serializable repo signals: + +```yaml +repo: + name: dev.kit + archetype: library-cli + profile: node + +refs: + - ./README.md + - ./package.json + +commands: + verify: make test + build: make build + +dependencies: + - repo: udx/reusable-workflows + type: reusable workflow + resolved: true + archetype: workflow-repo + used_by: + - .github/workflows/npm-release-ops.yml + +gaps: + - config (partial) +``` + +**`AGENTS.md`** — generated execution artifact for agents. It should stay simpler than `context.yaml`: rules, workflow, verification, and how to use current GitHub and learned context without duplicating refs, manifests, or dependency maps already serialized in `context.yaml`. + +Together, these two artifacts create a disciplined loop: + +- `context.yaml` says what the repo declares and what dev.kit could trace +- `AGENTS.md` says how to act on that contract using live GitHub experience first + +--- + +## Commands + +| Command | What it does | +|---------|-------------| +| `dev.kit` | Check environment, detect repo, show next step | +| `dev.kit repo` | Analyze factors, trace dependencies, pull GitHub signals, write `context.yaml` | +| `dev.kit repo --force` | Re-resolve all dependencies from scratch | +| `dev.kit agent` | Generate `AGENTS.md` from `context.yaml` | +| `dev.kit learn` | Extract patterns from Claude/Codex sessions into lessons artifact | + +All commands support `--json` for machine-readable output. + +--- + +## Repo Context + +Repo context comes from repo source first: README, docs, workflows, manifests, tests, and other declared refs. `dev.kit repo` then traces and maps dependencies, commands, gaps, and other serializable signals into `context.yaml`. `AGENTS.md` turns that repo map into an operating contract for agents, using current GitHub context as the primary dynamic input and repo workflow/practice catalogs as fallback defaults. + +That means dev.kit does not just tell an agent what files exist. It also pushes the session toward the repo's real delivery loop: branch naming based on repo history, issue and PR writing based on existing patterns, bot feedback loops, and workflow status checks before close-out. + +## Cross-repo tracing + +Traces dependencies from 6 sources: workflow reuse, GitHub actions, Docker images, versioned YAML, GitHub URLs, npm packages. + +Same-org repos resolved via `gh api` + sibling directory. Docker images mapped to source repos automatically. + +```yaml +# udx/rabbit-automation-action +dependencies: + - repo: udx/gh-workflows + type: reusable workflow + resolved: true + + - repo: usabilitydynamics/udx-worker-tooling:0.19.0 + type: base image + resolved: true + source_repo: udx/worker-tooling +``` + +--- + +## Install + +```bash +# npm (recommended) +npm install -g @udx/dev-kit + +# no npm? +curl -fsSL https://raw.githubusercontent.com/udx/dev.kit/latest/bin/scripts/install.sh | bash +``` + +Use one install path at a time. Installing with npm removes the curl-managed `~/.udx/dev.kit` home and shim. Installing with curl removes the global `@udx/dev-kit` package before laying down the local shim and home directory. + +--- + +## Docs + +- [Installation](docs/installation.md) — npm and curl installs, cleanup, uninstall, and verification +- [Context](docs/context.md) — `.rabbit/context.yaml`, its sections, and how it is generated +- [Agents](docs/agents.md) — `AGENTS.md` generation and how agents use it +- [Integration](docs/integration.md) — how the CLI, repo context, and agent workflow fit together diff --git a/bin/dev-kit b/bin/dev-kit index ec476c8..4d8632d 100755 --- a/bin/dev-kit +++ b/bin/dev-kit @@ -38,7 +38,8 @@ usage() { local command_name="" local description="" cat <<'EOF' -Usage: dev.kit +Usage: dev.kit [--json] + dev.kit Commands: EOF @@ -61,34 +62,36 @@ EOF home_usage() { echo "Usage: dev.kit [--json]" echo - echo "Shows repo-aware landing output for the current directory." + echo "Checks environment, refreshes repo context, and generates agent guidance when a repo is detected." } dev_kit_run_home() { local format="${1:-text}" local state="installed" local repo_dir="$(pwd)" + local repo_root="" repo_detected="false" repo_kind="workspace" + local archetype="n/a" profile="n/a" git_state="no" + local priority_refs="" next_git_action="" + local context_yaml_path="" agents_md_path="" - # JSON mode: compute everything up front then emit - if [ "$format" = "json" ]; then - local repo_root="" repo_detected="false" repo_kind="workspace" - local archetype="n/a" profile="n/a" git_state="no" - local priority_refs="" next_git_action="" - - repo_root="$(dev_kit_repo_root "$repo_dir")" - if [ -n "$repo_root" ]; then - repo_detected="true" - repo_kind="repo" - archetype="$(dev_kit_repo_primary_archetype "$repo_root")" - profile="$(dev_kit_repo_primary_profile "$repo_root")" - if dev_kit_sync_has_git_repo "$repo_root"; then - git_state="yes" - fi - priority_refs="$(dev_kit_repo_priority_refs "$repo_root")" - if [ "$git_state" = "yes" ]; then - next_git_action="$(dev_kit_sync_next_hint "$repo_root")" - fi + repo_root="$(dev_kit_repo_root "$repo_dir")" + if [ -n "$repo_root" ]; then + repo_detected="true" + repo_kind="repo" + archetype="$(dev_kit_repo_primary_archetype "$repo_root")" + profile="$(dev_kit_repo_primary_profile "$repo_root")" + context_yaml_path="$(dev_kit_context_yaml_path "$repo_root")" + agents_md_path="${repo_root}/AGENTS.md" + if dev_kit_sync_has_git_repo "$repo_root"; then + git_state="yes" fi + priority_refs="$(dev_kit_repo_priority_refs "$repo_root")" + if [ "$git_state" = "yes" ]; then + next_git_action="$(dev_kit_sync_next_hint "$repo_root")" + fi + + dev_kit_context_yaml_write "$repo_root" >/dev/null + dev_kit_agent_write_agents_md "$repo_root" "$agents_md_path" fi if [ "$format" = "json" ]; then @@ -115,6 +118,11 @@ dev_kit_run_home() { printf '\n' fi printf ' },\n' + printf ' "synced": {\n' + printf ' "repo_detected": %s,\n' "$repo_detected" + printf ' "context": %s,\n' "$(if [ -n "$context_yaml_path" ]; then printf '"%s"' "$(dev_kit_json_escape "$context_yaml_path")"; else printf 'null'; fi)" + printf ' "agents_md": %s\n' "$(if [ -n "$agents_md_path" ]; then printf '"%s"' "$(dev_kit_json_escape "$agents_md_path")"; else printf 'null'; fi)" + printf ' },\n' printf ' "localhost_tools": %s,\n' "$(dev_kit_env_tools_json)" printf ' "global_context": { "capabilities": %s },\n' "$(dev_kit_global_context_capabilities_json)" if [ "$repo_detected" = "true" ] && [ "$git_state" = "yes" ]; then @@ -125,6 +133,7 @@ dev_kit_run_home() { printf ' "agent_contract": [],\n' fi printf ' "helpers": [\n' + printf ' { "id": "env", "label": "Inspect environment tools and config", "command": "dev.kit env" },\n' printf ' { "id": "repo", "label": "Analyse repo structure and factors", "command": "dev.kit repo" },\n' printf ' { "id": "agent", "label": "Start an AI session with repo context", "command": "dev.kit agent" },\n' printf ' { "id": "learn", "label": "Review lessons-learned workflow", "command": "dev.kit learn" }\n' @@ -152,29 +161,26 @@ $(dev_kit_env_tools_text) EOF # ── Repo detection ────────────────────────────────────────────────────────── - local repo_root="" - repo_root="$(dev_kit_repo_root "$repo_dir")" - if [ -n "$repo_root" ]; then - dev_kit_spinner_start "detecting repo" - local archetype profile + dev_kit_spinner_start "syncing repo context" archetype="$(dev_kit_repo_primary_archetype "$repo_root")" profile="$(dev_kit_repo_primary_profile "$repo_root")" + context_yaml_path="$(dev_kit_context_yaml_path "$repo_root")" + agents_md_path="${repo_root}/AGENTS.md" + dev_kit_context_yaml_write "$repo_root" >/dev/null + dev_kit_agent_write_agents_md "$repo_root" "$agents_md_path" dev_kit_spinner_stop "" dev_kit_output_summary "$(dev_kit_repo_name "$repo_root") • ${archetype} • profile ${profile}" - dev_kit_output_section "do next" - # Guide to the next required step in the pipeline - local _context_yaml="${repo_root}/.rabbit/context.yaml" - local _agents_md="${repo_root}/AGENTS.md" - if [ ! -f "$_context_yaml" ]; then - dev_kit_output_row "required" "dev.kit repo — analyse repo and write context.yaml" - elif [ ! -f "$_agents_md" ]; then - dev_kit_output_row "required" "dev.kit agent — generate AGENTS.md from context" - else - dev_kit_output_row "required" "dev.kit repo — refresh context before starting work" - fi + dev_kit_output_section "synced" + dev_kit_output_row "context" "$context_yaml_path" + dev_kit_output_row "agents" "$agents_md_path" + + dev_kit_output_section "subcommands" + dev_kit_output_list_item 'Use `dev.kit env` to inspect tools and environment config.' + dev_kit_output_list_item 'Use `dev.kit repo` to refresh only repo context.' + dev_kit_output_list_item 'Use `dev.kit agent` to regenerate only `AGENTS.md`.' else dev_kit_output_summary "no repo detected at ${repo_dir}" dev_kit_output_section "do next" @@ -193,6 +199,10 @@ command_usage() { echo " --check Report gaps without writing context.yaml" echo " --force Re-resolve all dependencies from scratch" ;; + env) + echo " --json Output machine-readable JSON" + echo " --config Create or inspect the environment config file" + ;; agent) echo " --json Output machine-readable JSON" ;; diff --git a/config/env.yaml b/config/env.yaml new file mode 100644 index 0000000..4b098ed --- /dev/null +++ b/config/env.yaml @@ -0,0 +1,6 @@ +kind: envConfig +version: udx.io/dev.kit/v1 + +config: + disabled_tools: [] + disabled_credentials: [] diff --git a/docs/agents.md b/docs/agents.md deleted file mode 100644 index a955a59..0000000 --- a/docs/agents.md +++ /dev/null @@ -1,167 +0,0 @@ -# Agents - -`dev.kit agent` turns repo context into agent instructions. - -Its main output is `AGENTS.md`, generated from `.rabbit/context.yaml` plus the repo's workflow, practice, and learning inputs. - -## Role - -If `context.yaml` answers what is known, `AGENTS.md` answers how an agent should operate. - -This is the behavior layer. It tells an agent how to use the fetched repo contract efficiently and with minimal drift. - -`AGENTS.md` should stay simpler than `context.yaml`. It is a built artifact, not the full repo map. - -One core rule should stay explicit: start each new interaction or session by rerunning: - -```bash -dev.kit -dev.kit repo -dev.kit agent -``` - -That keeps repo context, workflow expectations, and generated instructions in sync before deeper work. - -## What It Generates - -Run: - -```bash -dev.kit agent -``` - -This writes `AGENTS.md`. If `.rabbit/context.yaml` does not exist yet, `dev.kit agent` generates context first. - -## Why `AGENTS.md` Exists - -Raw repo facts are not enough. Agents still need explicit operating instructions for how to read, decide, verify, and hand work off. - -`AGENTS.md` exists to define: - -- session-start and interaction-start behavior -- context boundaries -- what to read first -- how to prioritize manifests over implementation -- how to follow the repo workflow -- how to choose between GitHub workflow verification and local verification -- how to use current GitHub history as the primary dynamic source -- how to fall back to repo workflow, practice catalogs, and lessons without drifting -- how to loop on PR reviews, status checks, and follow-up comments until delivery is actually clean - -## Inputs - -`AGENTS.md` is generated from repo evidence, not handwritten prompt text: - -- `.rabbit/context.yaml` -- YAML workflow and practice catalogs in `src/configs/` -- GitHub repo context when available -- lessons from prior agent sessions - -That keeps the instructions grounded and refreshable. - -The intended decision order is: - -1. current repo contract from `.rabbit/context.yaml` -2. current GitHub experience for this repo -3. repo-declared default workflows and practices -4. prior lessons and other secondary history - -That order matters. `AGENTS.md` should keep agents from skipping straight to implementation when the repo already has issue history, open PR discussion, branch conventions, workflow results, or bot feedback that should shape the next action. - -## Main Sections - -The generated contract typically includes: - -- rules -- repo commands -- priority refs -- config manifests -- external dependencies -- GitHub context -- workflow steps -- learned practices - -## What Belongs Here - -`AGENTS.md` is where dynamic execution guidance belongs. - -That includes: - -- how an agent should start each session -- how an agent should interpret repo context -- how an agent should use GitHub issues, PRs, and recent history first -- how an agent should sequence work and verification -- how an agent should avoid scanning and guesswork - -This is also where dev.kit can keep common GitHub-facing behaviors explicit, for example: - -- derive branch, issue, and PR naming from current repo patterns -- write PR bodies and issue updates in the style the repo already uses -- monitor workflow runs after a push -- read bot feedback, reply, fix, and resolve threads before human review - -Verification should follow the same priority: - -1. detect the repo's canonical verify surface from `context.yaml` -2. prefer GitHub workflow executions and monitor them when the repo already has CI coverage -3. use local verification when GitHub coverage is missing, when a workflow failure needs local reproduction, or when a quick scoped local check is the fastest way to debug - -So `AGENTS.md` should acknowledge local verify commands from repo context, but it should not enforce local execution as a universal rule. - -After a PR exists, the same contract should stay explicit: - -1. monitor related GitHub workflow executions and status checks -2. loop bot feedback on the PR -3. fix issues, reply to comments, and resolve threads -4. repeat until workflow state and bot feedback are clean - -It should not restate: - -- priority refs -- manifest inventories -- dependency maps - -Those already belong in `.rabbit/context.yaml`. - -This is the layer that combines static repo contract with current repo experience. - -## Relationship To `.rabbit/context.yaml` - -`.rabbit/context.yaml` is the structured repo map. - -`AGENTS.md` is the agent-facing execution contract built on top of that map. - -A useful shorthand is: - -- `context.yaml` = fetched and serialized repo knowledge -- `AGENTS.md` = instructions for using that knowledge well - -They should stay separate, but tightly coupled. - -`context.yaml` should stay factual and serializable. - -`AGENTS.md` should stay directive, current-state aware, and smaller. - -## Efficiency Goal - -The best result is a short path from repo state to grounded agent action: - -1. `context.yaml` tells the agent what exists and what was detected. -2. `AGENTS.md` tells the agent how to act on that information. -3. The agent spends less time rediscovering the repo and more time doing scoped work. - -## JSON Surface - -For machine-readable agent integration, use: - -```bash -dev.kit agent --json -``` - -The JSON template for that surface is: - -- `src/templates/agent.json` - -## Provider-Agnostic - -`AGENTS.md` is not tied to one model or tool. The goal is a repo-native execution contract that can guide Codex, Claude, Gemini, Copilot, or other agents without rewriting the repo’s expectations for each provider. diff --git a/docs/context-coverage.md b/docs/context-coverage.md new file mode 100644 index 0000000..51873c1 --- /dev/null +++ b/docs/context-coverage.md @@ -0,0 +1,61 @@ +# Context Coverage + +`.rabbit/context.yaml` is the structured coverage report for the repository. + +It should answer three questions: + +1. what did `dev.kit` detect? +2. what can be serialized cleanly? +3. what is still missing or only partial? + +## What It Covers + +`context.yaml` is for facts and deterministic transforms built from repo signals. + +Typical sections include: + +- repo identity +- priority refs +- detected verify, build, and run commands +- gaps +- manifests +- dependencies +- lessons + +Depending on the repo and environment, it may also include live repo experience that can be serialized safely. + +## What Gaps Mean + +`gaps` is not a generic TODO list. It is the set of engineering factors that `dev.kit` could not confirm fully from the available signals. + +That means a gap can represent: + +- something missing +- something incomplete +- something present but too thin to treat as strong coverage + +This is why context coverage testing should include broken or degraded repos, not only healthy ones. + +## What Does Not Belong There + +`context.yaml` should not become a prompt or a workflow script. + +It is not the right place for: + +- agent behavior rules +- long-form operating guidance +- issue or PR handling advice +- subjective reasoning about what an agent should do next + +Those belong in `AGENTS.md`. + +## Coverage Strategy + +The coverage model is repo-first: + +- read README, docs, manifests, workflows, tests, and deploy config +- detect commands and factor signals +- trace deterministic dependencies +- report gaps where coverage is weak + +That keeps `context.yaml` useful both for healthy repos and for repos that need cleanup. diff --git a/docs/context.md b/docs/context.md deleted file mode 100644 index 7fa6f3e..0000000 --- a/docs/context.md +++ /dev/null @@ -1,141 +0,0 @@ -# Context - -`.rabbit/context.yaml` is the structured repo contract produced by `dev.kit repo`. - -It should answer: what can be fetched from this repo programmatically, what was detected, what is missing, and what other repos or workflows this repo depends on. - -## Role - -`context.yaml` is the machine-friendly map of the repository. It is not the place for agent policy, step-by-step behavior, or prompt-style instructions. - -Its boundary is best understood as two layers combined into one artifact: - -- base repo context signals -- deterministic tracing and mapping built from those signals - -Use it for facts such as: - -- repo identity -- priority refs -- canonical commands -- detected gaps -- manifests that define behavior -- traced dependencies and where they are used -- GitHub-derived repo experience that can be serialized cleanly - -## How It Is Produced - -Run: - -```bash -dev.kit repo -``` - -That command inspects repo-native signals, resolves what it can deterministically, and writes `.rabbit/context.yaml`. - -If the file is missing, `dev.kit agent` can generate it first before writing `AGENTS.md`. - -## What Feeds It - -`context.yaml` comes from evidence `dev.kit` can fetch or derive from the repo and its configured integrations: - -- README and docs -- manifests like `package.json`, `composer.json`, `Dockerfile` -- `.github/workflows/*` -- `deploy.yml` -- tests and command surfaces -- YAML config catalogs in `src/configs/` -- GitHub repo signals when available - -The important split is: - -- signals are the raw repo-facing inputs -- tracing and mapping are the deterministic transforms `dev.kit` performs on top of them - -Examples of tracing and mapping include: - -- detecting canonical verify, build, and run commands -- mapping reusable workflows to upstream repos -- mapping Docker images to likely source repos -- mapping versioned YAML contracts to upstream modules or repos -- mapping dependencies to the local files that use them - -The key boundary is simple: if `dev.kit` can detect it, trace it, or serialize it, it belongs here. - -## Main Sections - -The generated file in this repo currently includes: - -- `repo` -- `refs` -- `commands` -- `gaps` -- `dependencies` -- `manifests` -- `lessons` - -Depending on available integrations, it may also include GitHub-derived data. GitHub belongs here only when it can be fetched and serialized as repo experience data. It does not replace the repo contract. - -Examples of GitHub-derived data that fit here: - -- open pull requests -- recent pull request history -- linked issue references -- repo URLs that anchor the current work - -Those belong here because they can be serialized as current repo experience. Review decisions, step-by-step agent behavior, and how to respond to live findings still belong in `AGENTS.md`. - -## What Each Section Means - -`repo` identifies the repository through values such as `name`, `archetype`, and `profile`. - -`refs` is the priority reading list. It tells an agent or tool which files and directories matter first. - -This is the only place refs should live. `AGENTS.md` should point to `context.yaml`, not repeat the ref list. - -`commands` is the detected execution surface, such as `verify`, `build`, and `run`. - -`dependencies` is cross-repo tracing. Each entry explains what external repo, package, or workflow was referenced and which local files use it. - -`gaps` is a checklist of missing or partial factors `dev.kit` could detect programmatically. - -`manifests` lists the config files that define repo behavior. In `dev.kit`, these are first-class interfaces. - -`lessons` links prior session artifacts produced by `dev.kit learn`. - -## What Does Not Belong Here - -`context.yaml` should not try to be the final agent prompt. - -It is not where you explain: - -- how an agent should interpret ambiguity -- how an agent should sequence work for a user -- how an agent should balance repo context against current task context -- how an agent should loop on bot review comments -- how an agent should decide between local verification and GitHub workflow verification - -That layer belongs in `AGENTS.md`. - -## Efficiency Goal - -The point of `context.yaml` is compression without losing structure. - -It should let an agent answer questions like: - -- What commands exist? -- What docs and manifests matter first? -- What repo signals were used? -- What dependencies are real, and where are they used? -- Which engineering factors are missing? -- Which repo facts and traced signals are already available? - -If that data is available in `context.yaml`, the agent does not need to rediscover it by scanning. - -## JSON Contract - -For automation, the repo command JSON surface is defined by: - -- `src/templates/repo.json` - -That JSON output and `.rabbit/context.yaml` are the stable structured surfaces from `dev.kit repo`. diff --git a/docs/environment-config.md b/docs/environment-config.md new file mode 100644 index 0000000..0c29414 --- /dev/null +++ b/docs/environment-config.md @@ -0,0 +1,67 @@ +# Environment Config + +`dev.kit` is environment-aware. Generated output depends on what can actually be observed from the current machine, available tools, and allowed credentials. + +That is why environment detection is a first-class command: + +```bash +dev.kit env +``` + +## What `dev.kit env` Does + +`dev.kit env` reports: + +- required tools such as `git`, `gh`, `npm`, `docker`, `jq`, and `yq` +- cloud tools when present +- recommended helper tools +- the current env config file when it exists + +This lets `dev.kit` describe real capability instead of pretending GitHub, cloud, or dependency resolution is available when it is not. + +## `--config` + +Use: + +```bash +dev.kit env --config +``` + +This creates or updates: + +```text +$DEV_KIT_HOME/config/env.yaml +``` + +The goal is a small, explicit control surface for disabling tools or credentials you do not want `dev.kit` to use. + +## Config Shape + +Example: + +```yaml +kind: envConfig +version: udx.io/dev.kit/v1 + +config: + disabled_tools: + - gh + - docker + disabled_credentials: + - github + - aws +``` + +This does not uninstall tools or revoke credentials. It only changes what `dev.kit` treats as available for its own detection and guidance. + +## Why This Matters + +Environment state affects context coverage. + +Examples: + +- if `gh` is unavailable or disabled, GitHub-aware tracing and guidance should be thinner +- if a cloud credential is intentionally disabled, `dev.kit` should not claim that cloud path is usable +- if only local repo signals are available, generated output should stay grounded in those signals + +That makes the generated contract more honest and more reusable across local agents, remote agents, and controlled worker environments. diff --git a/docs/experience-guidance.md b/docs/experience-guidance.md new file mode 100644 index 0000000..4b02adb --- /dev/null +++ b/docs/experience-guidance.md @@ -0,0 +1,52 @@ +# Experience Guidance + +`AGENTS.md` is the generated operating layer built on top of `.rabbit/context.yaml`. + +Its purpose is not to restate the repo map. Its purpose is to help an agent operate from that repo map without drifting. + +## What It Should Do + +`AGENTS.md` should stay lightweight and role-aware. + +That means it should help with: + +- how to start from the repo contract +- what to read first +- how to prefer manifests over guesswork +- when to verify locally +- when live repo experience should matter more than defaults + +It should not force one fixed software-delivery script onto every agent role. + +## Repo Experience + +Current GitHub state is one possible live operating layer. + +For some tasks, issues, pull requests, reviews, and workflow runs are central. For others, the useful guidance may be more about repo structure, verification surface, deployment context, or operational signals. + +That is why generated guidance should be shaped by: + +- repo contract first +- live repo experience where it is relevant and available +- lessons and fallback defaults last + +## Why This Layer Exists + +Raw repo facts are necessary, but not sufficient. + +An agent still needs direction on how to use those facts. `AGENTS.md` is that direction layer, but it should remain smaller than `context.yaml` and should always point back to the repo contract instead of copying it. + +## Practical Rule + +The practical session-start rule remains simple: + +```bash +dev.kit +``` + +Then read: + +- `.rabbit/context.yaml` +- `AGENTS.md` + +That keeps each session anchored to current repo context instead of stale prompt memory. diff --git a/docs/how-it-works.md b/docs/how-it-works.md new file mode 100644 index 0000000..0a0a4df --- /dev/null +++ b/docs/how-it-works.md @@ -0,0 +1,62 @@ +# How It Works + +`dev.kit` has one primary job: turn repo-declared context into a working contract for agents. + +The happy path is: + +```bash +dev.kit +``` + +When a repo is detected, that one command: + +- checks the current environment +- refreshes `.rabbit/context.yaml` +- regenerates `AGENTS.md` +- points to the next focused subcommand when needed + +The lower-level commands still exist: + +- `dev.kit env` +- `dev.kit repo` +- `dev.kit agent` +- `dev.kit learn` + +Those are useful when only one layer needs to be refreshed, but the default experience should start from `dev.kit`. + +## Generated Artifacts + +`dev.kit` produces two core artifacts: + +- `.rabbit/context.yaml` +- `AGENTS.md` + +`.rabbit/context.yaml` is the structured repo contract. It contains repo identity, priority refs, detected commands, gaps, manifests, and dependency traces. + +`AGENTS.md` is the generated guidance layer for agents. It points back to `context.yaml` instead of duplicating it, and focuses on how the agent should operate from the repo contract. + +The intended split is: + +- `context.yaml` answers what the repo declares +- `AGENTS.md` answers how an agent should use that declaration + +## Command Roles + +`dev.kit env` inspects tools, auth state, and local env config. It is where local capability controls live. + +`dev.kit repo` analyzes the repository and writes `.rabbit/context.yaml`. + +`dev.kit agent` reads repo context and generates `AGENTS.md`. + +`dev.kit learn` extracts lessons from prior agent sessions into `.rabbit/dev.kit/`. + +## Working Model + +The working model is repo-first: + +1. read the repo’s declared context +2. serialize it into `context.yaml` +3. generate lightweight agent guidance from that context +4. let the current repo experience shape the next action + +That keeps the repo as the source of truth and reduces prompt drift between sessions. diff --git a/docs/installation.md b/docs/installation.md index 6c85326..c60614f 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -11,11 +11,9 @@ Installation only puts the command on the machine. The normal operating loop sta ```bash dev.kit -dev.kit repo -dev.kit agent ``` -That loop refreshes repo context, regenerates `AGENTS.md`, and makes the next work step explicit before an agent or developer starts changing the repo. +`dev.kit` is the happy path. It checks the environment, refreshes repo context, and regenerates `AGENTS.md` when a repo is detected. Use `dev.kit repo` or `dev.kit agent` only when you want to refresh one layer independently. ## Recommended Path @@ -101,13 +99,13 @@ After either install path, verify the active install with: dev.kit ``` -That confirms the command resolves correctly and shows the next step in the session flow. +That confirms the command resolves correctly and runs the normal guided flow when a repo is detected. -After that, continue with: +If you want to inspect or control environment capabilities directly, continue with: ```bash -dev.kit repo -dev.kit agent +dev.kit env +dev.kit env --config ``` -The goal is not only to confirm that the binary works. The goal is to start the session from current repo contract and current GitHub-aware workflow guidance rather than stale local memory. +Use `dev.kit repo` and `dev.kit agent` separately only when one generated artifact needs to be refreshed on its own. diff --git a/docs/integration.md b/docs/integration.md deleted file mode 100644 index 5661876..0000000 --- a/docs/integration.md +++ /dev/null @@ -1,120 +0,0 @@ -# Integration - -`dev.kit` works because it separates repo knowledge from agent behavior, then links them in one session flow. - -The goal is not to generate more files. The goal is to reduce uncertainty about what exists, what matters, and how to act. - -Another way to say it: dev.kit is middleware between repo-declared context and live GitHub experience. It keeps agents and developers grounded in the repo contract, then points them toward the current issue, PR, review, and workflow state that should drive the next decision. - -## Core Flow - -The integration model starts with three commands: - -```bash -dev.kit -dev.kit repo -dev.kit agent -``` - -Those commands connect five layers: - -1. local environment detection -2. structured repo context generation -3. deterministic tracing and mapping -4. agent contract generation -5. human or agent execution - -For agents, this is not only a first-time setup flow. It is the resync loop. On each new interaction or session, rerun the flow so the next action starts from current repo context rather than stale memory. - -## Separation Of Responsibilities - -The split should stay explicit: - -- `dev.kit repo` produces `.rabbit/context.yaml` -- `dev.kit agent` produces `AGENTS.md` - -`context.yaml` is the fetched map of the repo and its detectable signals. - -`AGENTS.md` is the operating contract that tells an agent how to use that map together with current GitHub context, learned patterns, and repo workflow defaults. - -That separation keeps both artifacts smaller and more reliable. - -In practice: - -- `context.yaml` owns refs, manifests, commands, dependencies, and gaps -- `AGENTS.md` points back to `context.yaml` and stays focused on workflow, practices, and behavior - -## Developer Integration - -For developers, `dev.kit` provides: - -- a quick environment check -- a generated summary of repo factors and gaps -- a canonical command surface for verify, build, and run -- a repeatable way to understand repo expectations before changing code - -This reduces time spent rediscovering how a repo works. - -It also shortens common GitHub loops. Instead of inventing a new branch name, PR structure, or issue update style each time, the repo contract can point the session back to current repo patterns and current review state first. - -## Agent Integration - -For agents, `dev.kit` provides: - -- a structured reading surface in `context.yaml` -- config and workflow manifests as first-class interfaces -- a behavior contract in `AGENTS.md` -- JSON output for automation and toolchains - -This means agents can spend less effort on discovery and more effort on scoped execution. - -That execution should stay GitHub-aware. The intended behavior is not just "read files, then code." It is "refresh repo contract, inspect current GitHub experience, act, then loop on workflows and automated review until the change is actually ready." - -## GitHub And History - -GitHub and learning data are most useful when they support agent decisions, not when they blur the repo map. - -In practice: - -- repo and integration signals can be serialized into `context.yaml` -- current issues, PRs, and repo history are the primary dynamic inputs in `AGENTS.md` -- workflow expectations and practice catalogs act as fallback defaults in `AGENTS.md` -- lessons remain secondary memory that should not outrank live repo or GitHub state - -That gives agents both structure and recency without mixing roles. - -## Workflow Integration - -The generated workflow is intended to fit into normal engineering work: - -1. start the session with `dev.kit`, `dev.kit repo`, and `dev.kit agent` -2. read the generated repo contract and agent contract -3. inspect current GitHub issue, PR, review, and branch context before inventing a new path -4. do the actual implementation or review work -5. verify through the repo-declared surface, preferring GitHub workflow runs when the repo already has CI coverage -6. loop on bot reviews, workflow failures, and follow-up comments until the delivery chain is clean -7. optionally run `dev.kit learn` so session outcomes feed future runs - -## Config-Driven Integration - -`dev.kit` does not rely on hidden prompt rules. It integrates through repo-owned config and workflow assets: - -- `src/configs/*.yaml` -- workflow files -- repo manifests -- docs -- tests - -That makes behavior inspectable, versioned, and reusable. - -## Efficiency Goal - -The best integration is: - -- `context.yaml` stays factual and structured -- tracing and mapping stay deterministic -- `AGENTS.md` stays directive and execution-oriented -- GitHub experience stays the primary dynamic source for agent judgment -- both are regenerated cheaply at session start - -That gives developers and agents one contract with two surfaces instead of two competing sources of truth. diff --git a/docs/smart-dependency-detection.md b/docs/smart-dependency-detection.md new file mode 100644 index 0000000..5316604 --- /dev/null +++ b/docs/smart-dependency-detection.md @@ -0,0 +1,41 @@ +# Smart Dependency Detection + +`dev.kit repo` does more than list local files. It also traces dependencies that shape how the repo really works. + +## What It Detects + +Cross-repo tracing currently covers sources such as: + +- reusable GitHub workflows +- GitHub actions +- Docker images +- versioned YAML references +- GitHub URLs +- npm packages + +These are then mapped into dependency entries in `.rabbit/context.yaml`. + +## Resolution Model + +The tracing model is deterministic. + +If `dev.kit` can resolve a dependency confidently, it records: + +- the dependency target +- its type +- whether it was resolved +- where it is used in the current repo + +When possible, same-org dependencies are resolved from current GitHub metadata and local sibling repos. Docker images may also be mapped back to likely source repos. + +## Why It Matters + +This is what makes `context.yaml` more useful than a plain file inventory. + +A repo often depends on workflows, images, or external modules that live elsewhere. If those relationships are visible in the generated contract, an agent can trace execution paths faster and with less guesswork. + +## Coverage Limits + +Dependency detection still follows the same rule as the rest of `dev.kit`: report what can actually be observed. + +If a dependency cannot be resolved confidently from the available repo and environment signals, it should remain partial rather than be invented. diff --git a/lib/commands/agent.sh b/lib/commands/agent.sh index 9458faf..4efc7a9 100644 --- a/lib/commands/agent.sh +++ b/lib/commands/agent.sh @@ -129,49 +129,34 @@ dev_kit_agent_github_section() { ' "$context_yaml" } -dev_kit_agent_practice_lines() { - local practices_file="" - practices_file="$(dev_kit_practices_config_path)" - [ -f "$practices_file" ] || return 0 - - awk ' - $1 == "config:" { in_config = 1; next } - in_config && $1 == "practices:" { in_practices = 1; next } - in_practices && $1 == "-" && $2 == "id:" { next } - in_practices && $1 == "message:" { - $1 = "" - sub(/^ /, "") - printf " - %s\n", $0 - } - ' "$practices_file" -} - dev_kit_agent_workflow_lines() { - local workflow_file="" - workflow_file="$(dev_kit_workflow_config_path)" - - if [ -f "$workflow_file" ]; then - awk ' - /^ - id:/ { flush(); label=""; note=""; in_note=0; next } - /^ label:/ { sub(/^[[:space:]]*label:[[:space:]]*/, "", $0); label=$0; next } - /^ note:[[:space:]]*>/ { in_note=1; next } - in_note && /^ / { - sub(/^[[:space:]]+/, "", $0) - note = (note == "") ? $0 : note " " $0 - next - } - in_note { flush(); in_note=0 } - function flush() { - if (label == "") return - if (note != "") printf " - %s: %s\n", label, note - else printf " - %s\n", label - } - END { flush() } - ' "$workflow_file" - return 0 - fi + local repo_dir="${1:-$(pwd)}" + local step_line="" + local step_label="" + local step_command="" + + while IFS= read -r step_line; do + [ -n "$step_line" ] || continue + step_line="${step_line#*|}" + step_label="${step_line%%|*}" + step_command="${step_line#*|}" + if [ -n "$step_command" ]; then + printf ' - %s: %s\n' "$step_label" "$step_command" + else + printf ' - %s\n' "$step_label" + fi + done </dev/null || true +dev_kit_agent_principle_lines() { + cat <<'EOF' + - Start from `.rabbit/context.yaml`, then read only the highest-priority repo refs it points to. + - Prefer repo-declared commands, manifests, workflows, and tests over ad hoc exploration. + - Treat current GitHub state as useful live context when available, not as a mandatory workflow for every task. + - Keep generated guidance lightweight. Do not duplicate repo context already serialized in `.rabbit/context.yaml`. +EOF } # Write AGENTS.md — the repo's execution contract for AI agents. @@ -274,7 +259,7 @@ dev_kit_agent_write_agents_md() { _workflow="$(dev_kit_agent_workflow_lines "$repo_dir")" if [ -n "$_workflow" ]; then printf '## Workflow\n\n' - printf 'The dev.kit lifecycle: **repo → agent → work → PR → merge**. Follow these steps in order. Use them as repo-declared defaults when live GitHub context does not provide a more specific current signal. Steps with notes contain operational guidance.\n\n' + printf 'Use these repo-derived steps as the default operating path. Adapt them to the current agent role instead of forcing a single development lifecycle onto every task.\n\n' printf '%s\n\n' "$_workflow" fi @@ -371,7 +356,7 @@ EOF # ── Principles — engineering practices ─────────────────────────────────── local _practices - _practices="$(dev_kit_agent_practice_lines)" + _practices="$(dev_kit_agent_principle_lines)" if [ -n "$_practices" ]; then printf '## Engineering practices\n\n%s\n\n' "$_practices" fi diff --git a/lib/commands/env.sh b/lib/commands/env.sh new file mode 100644 index 0000000..c4f4d68 --- /dev/null +++ b/lib/commands/env.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash + +# @description: Inspect environment tools and dev.kit usage config + +dev_kit_cmd_env() { + local format="${1:-text}" + local manage_config=0 + + if [ "$#" -ge 1 ]; then + shift + fi + + while [ "$#" -gt 0 ]; do + case "$1" in + --config) manage_config=1 ;; + --*) + printf 'Unknown flag: %s\n' "$1" >&2 + printf 'Usage: dev.kit env [--json] [--config]\n' >&2 + return 1 + ;; + esac + shift + done + + if [ "$manage_config" -eq 1 ]; then + dev_kit_env_config_ensure + fi + + local config_path disabled_tools disabled_credentials + config_path="$(dev_kit_env_config_path)" + disabled_tools="$(dev_kit_env_config_list "disabled_tools")" + disabled_credentials="$(dev_kit_env_config_list "disabled_credentials")" + + if [ "$format" = "json" ]; then + printf '{\n' + printf ' "command": "env",\n' + printf ' "home": "%s",\n' "$(dev_kit_json_escape "$DEV_KIT_HOME")" + printf ' "tools": %s,\n' "$(dev_kit_env_tools_json)" + printf ' "capabilities": %s,\n' "$(dev_kit_global_context_capabilities_json)" + printf ' "config": {\n' + printf ' "path": "%s",\n' "$(dev_kit_json_escape "$config_path")" + printf ' "exists": %s,\n' "$([ -f "$config_path" ] && printf 'true' || printf 'false')" + printf ' "disabled_tools": %s,\n' "$(printf '%s' "$disabled_tools" | dev_kit_lines_to_json_array)" + printf ' "disabled_credentials": %s\n' "$(printf '%s' "$disabled_credentials" | dev_kit_lines_to_json_array)" + printf ' }\n' + printf '}\n' + return 0 + fi + + dev_kit_output_title "dev.kit env" + + local _env_line _env_cat _env_val _prev_cat="" + while IFS= read -r _env_line; do + [ -n "$_env_line" ] || continue + _env_cat="${_env_line%%|*}" + _env_val="${_env_line#*|}" + if [ "$_env_cat" != "$_prev_cat" ]; then + dev_kit_output_section "$_env_cat" + _prev_cat="$_env_cat" + fi + dev_kit_output_list_item "$_env_val" + done </dev/null || printf '0')" + gap_count="$(printf '%s\n' "$gaps_json" | grep -c '"factor"' 2>/dev/null || true)" + gap_count="${gap_count:-0}" if [ "$gap_count" -gt 0 ]; then dev_kit_output_section "gaps" dev_kit_output_list_item "${gap_count} factor(s) missing or partial" diff --git a/lib/modules/bootstrap.sh b/lib/modules/bootstrap.sh index 1ca42d6..d4b2782 100644 --- a/lib/modules/bootstrap.sh +++ b/lib/modules/bootstrap.sh @@ -30,7 +30,7 @@ dev_kit_command_description() { } dev_kit_public_command_names() { - printf '%s\n' repo agent learn uninstall + printf '%s\n' env repo agent learn uninstall } dev_kit_command_file_path() { diff --git a/lib/modules/config_catalog.sh b/lib/modules/config_catalog.sh index 583cb8d..e13ce6e 100644 --- a/lib/modules/config_catalog.sh +++ b/lib/modules/config_catalog.sh @@ -1,37 +1,26 @@ #!/usr/bin/env bash -DEV_KIT_KNOWLEDGE_CONFIG_FILE="src/configs/knowledge-base.yaml" DEV_KIT_LEARNING_CONFIG_FILE="src/configs/learning-workflows.yaml" DEV_KIT_LEARNING_DEFAULT_WORKFLOW="pr-lessons" -DEV_KIT_PRACTICES_CONFIG_FILE="src/configs/development-practices.yaml" -DEV_KIT_WORKFLOW_CONFIG_FILE="src/configs/development-workflows.yaml" dev_kit_config_path() { printf "%s/%s" "$REPO_DIR" "$1" } -dev_kit_archetype_signals_path() { - dev_kit_config_path "src/configs/archetype-signals.yaml" -} - -dev_kit_archetype_rules_path() { - dev_kit_config_path "src/configs/archetype-rules.yaml" -} - -dev_kit_archetype_signal_list() { - dev_kit_yaml_config_list "$(dev_kit_archetype_signals_path)" "$1" +dev_kit_archetypes_path() { + dev_kit_config_path "src/configs/archetypes.yaml" } dev_kit_archetype_rule_ids() { - dev_kit_yaml_named_block_ids "$(dev_kit_archetype_rules_path)" "archetypes" + dev_kit_yaml_named_block_ids "$(dev_kit_archetypes_path)" "archetypes" } dev_kit_archetype_facets() { - dev_kit_yaml_nested_mapping_list "$(dev_kit_archetype_rules_path)" "archetypes" "$1" "$2" + dev_kit_yaml_nested_mapping_list "$(dev_kit_archetypes_path)" "archetypes" "$1" "$2" } dev_kit_archetype_description() { - dev_kit_yaml_named_block_scalar "$(dev_kit_archetype_rules_path)" "archetypes" "$1" "description" + dev_kit_yaml_named_block_scalar "$(dev_kit_archetypes_path)" "archetypes" "$1" "description" } dev_kit_context_config_path() { @@ -86,28 +75,6 @@ dev_kit_repo_doc_refs() { dev_kit_repo_priority_list "${1:-$(pwd)}" "repo_doc_paths" } -dev_kit_knowledge_config_path() { - dev_kit_config_path "$DEV_KIT_KNOWLEDGE_CONFIG_FILE" -} - -dev_kit_knowledge_local_repos_root() { - dev_kit_yaml_mapping_scalar "$(dev_kit_knowledge_config_path)" "hierarchy" "local_repos_root" -} - -dev_kit_knowledge_remote_org_root() { - dev_kit_yaml_mapping_scalar "$(dev_kit_knowledge_config_path)" "hierarchy" "remote_org_root" -} - -dev_kit_knowledge_hierarchy_json() { - printf '{ "local_repos_root": "%s", "remote_org_root": "%s" }' \ - "$(dev_kit_json_escape "$(dev_kit_knowledge_local_repos_root)")" \ - "$(dev_kit_json_escape "$(dev_kit_knowledge_remote_org_root)")" -} - -dev_kit_knowledge_preferred_sources() { - dev_kit_yaml_nested_mapping_list "$(dev_kit_knowledge_config_path)" "sources" "preferred" "items" -} - dev_kit_learning_config_path() { dev_kit_config_path "$DEV_KIT_LEARNING_CONFIG_FILE" } @@ -238,39 +205,6 @@ EOF printf "]" } -dev_kit_practices_config_path() { - dev_kit_config_path "$DEV_KIT_PRACTICES_CONFIG_FILE" -} - -dev_kit_practice_message() { - local practice_id="$1" - - awk -v practice_id="$practice_id" ' - $1 == "config:" { in_config = 1; next } - in_config && $1 == "practices:" { in_practices = 1; next } - in_practices && $1 == "-" && $2 == "id:" { - current_id = $3 - in_target = (current_id == practice_id) - next - } - in_target && $1 == "message:" { - $1 = "" - sub(/^ /, "") - print - exit - } - ' "$(dev_kit_practices_config_path)" -} - -dev_kit_practice_message_list() { - local practice_id="" - - for practice_id in "$@"; do - [ -n "$practice_id" ] || continue - dev_kit_practice_message "$practice_id" - done -} - dev_kit_rule_catalog_path() { dev_kit_config_path "src/configs/audit-rules.yaml" } @@ -305,99 +239,3 @@ dev_kit_rule_field() { dev_kit_rule_message() { dev_kit_rule_field "$1" "message" } - -dev_kit_workflow_config_path() { - dev_kit_config_path "$DEV_KIT_WORKFLOW_CONFIG_FILE" -} - -dev_kit_workflow_default_scalar() { - dev_kit_yaml_mapping_scalar "$(dev_kit_workflow_config_path)" "defaults" "$1" -} - -dev_kit_workflow_default_list() { - dev_kit_yaml_mapping_list "$(dev_kit_workflow_config_path)" "defaults" "$1" -} - -dev_kit_sync_default_workflow() { - dev_kit_workflow_default_scalar "workflow" -} - -dev_kit_sync_behavior() { - dev_kit_workflow_default_scalar "behavior" -} - -dev_kit_sync_default_hooks_dir() { - dev_kit_workflow_default_scalar "hooks_dir" -} - -dev_kit_sync_text_max_next_steps() { - dev_kit_workflow_default_scalar "text_max_next_steps" -} - -dev_kit_sync_branch_role_base() { - dev_kit_yaml_nested_mapping_scalar "$(dev_kit_workflow_config_path)" "defaults" "branch_roles" "base" -} - -dev_kit_sync_branch_role_feature() { - dev_kit_yaml_nested_mapping_scalar "$(dev_kit_workflow_config_path)" "defaults" "branch_roles" "feature" -} - -dev_kit_sync_base_branch_names() { - dev_kit_workflow_default_list "base_branch_names" -} - -dev_kit_workflow_description() { - dev_kit_yaml_named_block_scalar "$(dev_kit_workflow_config_path)" "workflows" "$1" "description" -} - -dev_kit_workflow_name() { - dev_kit_yaml_named_block_scalar "$(dev_kit_workflow_config_path)" "workflows" "$1" "name" -} - -dev_kit_workflow_step_lines() { - local workflow_id="$1" - - awk -v workflow_id="$workflow_id" ' - $1 == "config:" { in_config = 1; next } - in_config && $0 ~ /^ workflows:/ { in_workflows = 1; next } - in_workflows && $0 ~ /^ [A-Za-z0-9_-]+:/ { - current = $1 - sub(":", "", current) - in_target = (current == workflow_id) - in_steps = 0 - step_id = "" - step_label = "" - step_check = "" - next - } - in_target && $0 ~ /^ steps:/ { - in_steps = 1 - next - } - in_steps && $0 ~ /^ - id:/ { - if (step_id != "") { - printf "%s|%s|%s\n", step_id, step_label, step_check - } - sub(/^[[:space:]]*-[[:space:]]*id:[[:space:]]*/, "", $0) - step_id = $0 - step_label = "" - step_check = "" - next - } - in_steps && $0 ~ /^ label:/ { - sub(/^[[:space:]]*label:[[:space:]]*/, "", $0) - step_label = $0 - next - } - in_steps && $0 ~ /^ check:/ { - sub(/^[[:space:]]*check:[[:space:]]*/, "", $0) - step_check = $0 - next - } - END { - if (step_id != "") { - printf "%s|%s|%s\n", step_id, step_label, step_check - } - } - ' "$(dev_kit_workflow_config_path)" -} diff --git a/lib/modules/dev_sync.sh b/lib/modules/dev_sync.sh index 73cbc2d..bb6adcd 100644 --- a/lib/modules/dev_sync.sh +++ b/lib/modules/dev_sync.sh @@ -3,6 +3,33 @@ DEV_KIT_SYNC_GH_AUTH_STATE_CACHE="" DEV_KIT_SYNC_GH_AUTH_STATE_CACHE_READY=0 +dev_kit_sync_default_hooks_dir() { + printf '%s' '.githooks' +} + +dev_kit_sync_text_max_next_steps() { + printf '%s' '4' +} + +dev_kit_sync_branch_role_base() { + printf '%s' 'base' +} + +dev_kit_sync_branch_role_feature() { + printf '%s' 'feature' +} + +dev_kit_sync_base_branch_names() { + cat <<'EOF' +latest +main +master +development +staging +trunk +EOF +} + dev_kit_sync_has_git_repo() { git -C "$1" rev-parse --git-dir >/dev/null 2>&1 } @@ -765,11 +792,9 @@ dev_kit_sync_step_state() { dev_kit_sync_step_lines() { local repo_dir="$1" - local workflow_id="${2:-$(dev_kit_sync_default_workflow)}" local step_line="" local step_id="" local step_label="" - local step_check="" local state_line="" local status="" local summary="" @@ -779,20 +804,17 @@ dev_kit_sync_step_lines() { step_id="${step_line%%|*}" step_line="${step_line#*|}" step_label="${step_line%%|*}" - step_line="${step_line#*|}" - step_check="${step_line%%|*}" state_line="$(dev_kit_sync_step_state "$repo_dir" "$step_id")" status="${state_line%%|*}" summary="${state_line#*|}" printf "%s|%s|%s|%s\n" "$step_id" "$step_label" "$status" "$summary" done < "$config_path" <<'EOF' +kind: envConfig +version: udx.io/dev.kit/v1 + +config: + disabled_tools: [] + disabled_credentials: [] +EOF + fi +} + +dev_kit_env_config_list() { + local list_name="$1" + local config_path="" + + config_path="$(dev_kit_env_config_path)" + [ -f "$config_path" ] || return 0 + + awk -v list_name="$list_name" ' + $1 == "config:" { in_config = 1; next } + in_config && $1 == list_name ":" { + in_list = 1 + line = $0 + if (line ~ /\[\]/) exit + next + } + in_list && /^[[:space:]]*-/ { + sub(/^[[:space:]]*-[[:space:]]*/, "", $0) + print + next + } + in_list && /^[^[:space:]]|^ [A-Za-z0-9_-]+:/ { exit } + ' "$config_path" +} + +dev_kit_env_config_has_value() { + local list_name="$1" + local value="$2" + local item="" + + while IFS= read -r item; do + [ -n "$item" ] || continue + [ "$item" = "$value" ] && return 0 + done </dev/null 2>&1; then _DEV_KIT_ENV_NPM_ROOT="$(npm root -g 2>/dev/null)" @@ -43,6 +114,11 @@ dev_kit_env_tool_state() { local tool="$1" local version="" + if dev_kit_env_tool_disabled "$tool"; then + printf 'disabled by config' + return 0 + fi + case "$tool" in "@udx/"*) local npm_root="" @@ -68,6 +144,11 @@ dev_kit_env_tool_state() { case "$tool" in gh) + if dev_kit_env_credential_disabled "gh"; then + version="$(dev_kit_env_tool_version "$tool")" + printf 'available (%s, auth disabled by config)' "${version:-installed}" + return 0 + fi case "$(dev_kit_sync_gh_auth_state)" in available) version="$(dev_kit_env_tool_version "$tool")" @@ -83,6 +164,15 @@ dev_kit_env_tool_state() { esac ;; *) + case "$tool" in + aws|gcloud|az) + if dev_kit_env_credential_disabled "$tool"; then + version="$(dev_kit_env_tool_version "$tool")" + printf 'available (%s, auth disabled by config)' "${version:-installed}" + return 0 + fi + ;; + esac version="$(dev_kit_env_tool_version "$tool")" if [ -n "$version" ]; then printf 'available (%s)' "$version" @@ -205,6 +295,9 @@ dev_kit_env_tools_text() { fi case "$status" in + disabled*) + printf '%s|○ %s — %s\n' "$category" "$tool" "$enables" + ;; missing) printf '%s|✗ %s — %s\n' "$category" "$tool" "$enables" ;; diff --git a/lib/modules/repo_archetypes.sh b/lib/modules/repo_archetypes.sh index fed8df3..36d1aec 100644 --- a/lib/modules/repo_archetypes.sh +++ b/lib/modules/repo_archetypes.sh @@ -5,52 +5,17 @@ DEV_KIT_REPO_FACETS_CACHE_VALUE="" DEV_KIT_REPO_ARCHETYPES_CACHE_REPO="" DEV_KIT_REPO_ARCHETYPES_CACHE_VALUE="" -dev_kit_repo_has_any_dir_from_signal_list() { +dev_kit_repo_has_kubernetes_manifest() { local repo_dir="$1" - local list_name="$2" - local path="" + local file_path="" - while IFS= read -r path; do - [ -n "$path" ] || continue - if dev_kit_repo_has_dir "$repo_dir" "$path"; then + while IFS= read -r file_path; do + [ -n "$file_path" ] || continue + if dev_kit_repo_file_has_all_patterns "$file_path" "yaml_api_version" "yaml_kind"; then return 0 fi done <