From da277197bf3d49f21f87e209326d8f190e4fb6ad Mon Sep 17 00:00:00 2001 From: Yasen Hu <74404492+HuYaSen@users.noreply.github.com> Date: Thu, 28 May 2026 17:17:48 +0800 Subject: [PATCH 1/3] =?UTF-8?q?chore(cmind):=20rename=20rpgkit=20=E2=86=92?= =?UTF-8?q?=20cmind=20across=20CoderMind=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surface-only rename to align the CLI command, Python package, and runtime paths with the CoderMind product name. Follow-up to #59 (which renamed RPG-Kit → CoderMind at the directory level only). Naming map: rpgkit → cmind (CLI command, slash-command prefix) rpgkit-cli → cmind-cli (wheel / package name) rpgkit_cli → cmind_cli (Python import package) rpgkit-mcp → cmind-mcp (MCP server console script) .rpgkit/, ~/.rpgkit/ → .cmind/, ~/.cmind/ (runtime directories) RPGKIT_* → CMIND_* (env vars, constants, gitignore markers) rpgkit-v* (release tag) → cmind-v* RPG-Kit → CoderMind (product name in docs/comments) Scope: - .github/workflows/{lint,release,pre-release}.yml + scripts/ dir renamed - CoderMind/src/rpgkit_cli/ renamed to cmind_cli/, all imports updated - CoderMind/pyproject.toml: package name, console scripts, wheel paths - CoderMind/scripts/, tests/, docs/, READMEs (incl. zh/ja/ko/hi) - templates/commands/* internal references - root README.md install/upgrade snippets + docs/cmind_visualized_graph.png Breaking change: existing `.rpgkit/` workspaces will not be auto-migrated. Users on v0.1.x need to re-run `cmind init` after upgrading. Historical release tags `rpgkit-v0.1.{1..4}` are kept; new releases will be tagged `cmind-v*`. Verified end-to-end: - `cmind init/update/version/check` smoke-tested in a clean workspace - All 13 e2e LLM agent stages PASS (encoder + decoder, parallel=2) - Unit tests: 909 pass; 29 pre-existing failures (unrelated to rename, confirmed by comparing against pre-rename main via git stash) --- .../{rpgkit-lint.yml => cmind-lint.yml} | 8 +- ...-pre-release.yml => cmind-pre-release.yml} | 16 +- .../{rpgkit-release.yml => cmind-release.yml} | 18 +- .../{rpgkit => cmind}/check-release-exists.sh | 0 .../create-github-release.sh | 6 +- .../create-release-packages.ps1 | 36 +- .../create-release-packages.sh | 32 +- .../generate-release-notes.sh | 8 +- .../{rpgkit => cmind}/get-next-pre-version.sh | 4 +- .../{rpgkit => cmind}/get-next-version.sh | 4 +- .../{rpgkit => cmind}/update-version.sh | 2 +- .gitignore | 4 +- .markdownlint-cli2.jsonc | 6 +- CoderMind/.gitignore | 16 +- CoderMind/.markdownlint-cli2.jsonc | 4 +- CoderMind/README.hi-IN.md | 106 +-- CoderMind/README.ja-JP.md | 104 +-- CoderMind/README.ko-KR.md | 104 +-- CoderMind/README.md | 88 +-- CoderMind/README.zh-CN.md | 104 +-- CoderMind/docs/cli-reference.md | 82 +- CoderMind/docs/commands.md | 224 +++--- CoderMind/docs/configuration.md | 130 ++-- CoderMind/docs/project-structure.md | 106 +-- CoderMind/pyproject.toml | 16 +- CoderMind/scripts/__init__.py | 8 +- CoderMind/scripts/build_data_flow.py | 8 +- CoderMind/scripts/build_skeleton.py | 26 +- CoderMind/scripts/check_base_classes.py | 2 +- CoderMind/scripts/check_code_gen.py | 10 +- CoderMind/scripts/check_data_flow.py | 4 +- CoderMind/scripts/check_interfaces.py | 2 +- CoderMind/scripts/check_skeleton.py | 8 +- CoderMind/scripts/check_tasks.py | 2 +- CoderMind/scripts/code_gen/__init__.py | 2 +- CoderMind/scripts/code_gen/batch_prompts.py | 10 +- .../scripts/code_gen/final_validation.py | 2 +- CoderMind/scripts/code_gen/global_review.py | 24 +- CoderMind/scripts/code_gen/rpg_updater.py | 2 +- CoderMind/scripts/code_gen/stage_io.py | 4 +- CoderMind/scripts/code_gen/static_checks.py | 2 +- CoderMind/scripts/code_gen/test_runner.py | 2 +- CoderMind/scripts/common/__init__.py | 8 +- CoderMind/scripts/common/execution_state.py | 8 +- CoderMind/scripts/common/git_utils.py | 8 +- CoderMind/scripts/common/llm_api_client.py | 4 +- CoderMind/scripts/common/llm_client.py | 22 +- CoderMind/scripts/common/llm_types.py | 4 +- CoderMind/scripts/common/logging_setup.py | 16 +- CoderMind/scripts/common/paths.py | 112 +-- CoderMind/scripts/common/rpg_io.py | 16 +- CoderMind/scripts/common/session_manager.py | 6 +- CoderMind/scripts/common/task_batch.py | 2 +- CoderMind/scripts/common/tools.py | 4 +- CoderMind/scripts/common/trajectory.py | 4 +- CoderMind/scripts/design_base_classes.py | 10 +- CoderMind/scripts/design_interfaces.py | 16 +- CoderMind/scripts/feature/__init__.py | 2 +- CoderMind/scripts/feature_build_validation.py | 10 +- CoderMind/scripts/feature_edit.py | 2 +- CoderMind/scripts/feature_edit_validation.py | 6 +- .../scripts/feature_refactor_validation.py | 10 +- CoderMind/scripts/feature_spec_to_json.py | 12 +- CoderMind/scripts/init_codebase.py | 70 +- CoderMind/scripts/mcp_server.py | 34 +- CoderMind/scripts/plan_tasks.py | 8 +- CoderMind/scripts/rpg/builder.py | 4 +- CoderMind/scripts/rpg/models.py | 14 +- CoderMind/scripts/rpg/service.py | 14 +- CoderMind/scripts/rpg_agent/env/env.py | 4 +- CoderMind/scripts/rpg_agent/ops/bm25_model.py | 2 +- CoderMind/scripts/rpg_agent/rpg_agent.py | 4 +- .../scripts/rpg_agent/tools/search_node.py | 2 +- CoderMind/scripts/rpg_edit/__init__.py | 4 +- CoderMind/scripts/rpg_edit/apply.py | 2 +- CoderMind/scripts/rpg_edit/code.py | 2 +- CoderMind/scripts/rpg_edit/review.py | 10 +- CoderMind/scripts/rpg_edit/save_plan.py | 4 +- CoderMind/scripts/rpg_edit/validate.py | 2 +- CoderMind/scripts/rpg_encoder/check_encode.py | 2 +- CoderMind/scripts/rpg_encoder/config.py | 50 +- .../scripts/rpg_encoder/refactor_tree.py | 2 +- CoderMind/scripts/rpg_encoder/rpg_encoding.py | 6 +- .../scripts/rpg_encoder/rpg_evolution.py | 6 +- CoderMind/scripts/rpg_encoder/run_encode.py | 20 +- .../scripts/rpg_encoder/run_update_rpg.py | 12 +- .../scripts/rpg_encoder/semantic_parsing.py | 2 +- .../scripts/rpg_encoder/version_control.py | 16 +- CoderMind/scripts/rpg_encoder/workflow.py | 28 +- CoderMind/scripts/rpg_visualize.py | 2 +- CoderMind/scripts/run_batch.py | 4 +- CoderMind/scripts/smoke_test.py | 2 +- CoderMind/scripts/summary_skeleton.py | 2 +- CoderMind/scripts/tools/browser.py | 10 +- CoderMind/scripts/tools/gui.py | 4 +- CoderMind/scripts/update_graphs.py | 50 +- .../src/{rpgkit_cli => cmind_cli}/__init__.py | 703 +++++++++--------- .../src/{rpgkit_cli => cmind_cli}/_assets.py | 24 +- .../{rpgkit_cli => cmind_cli}/_inner_git.py | 60 +- .../src/{rpgkit_cli => cmind_cli}/_storage.py | 84 +-- .../src/{rpgkit_cli => cmind_cli}/entries.py | 10 +- .../templates/commands/build_data_flow.md | 28 +- .../templates/commands/build_skeleton.md | 20 +- CoderMind/templates/commands/code_gen.md | 34 +- .../templates/commands/design_base_classes.md | 26 +- .../templates/commands/design_interfaces.md | 12 +- CoderMind/templates/commands/encode.md | 16 +- CoderMind/templates/commands/feature_build.md | 18 +- CoderMind/templates/commands/feature_edit.md | 28 +- .../templates/commands/feature_refactor.md | 20 +- CoderMind/templates/commands/feature_spec.md | 48 +- CoderMind/templates/commands/plan_tasks.md | 10 +- CoderMind/templates/commands/rpg_edit.md | 44 +- CoderMind/templates/commands/update_rpg.md | 20 +- .../tests/fixtures/sample_repo/README.md | 2 +- CoderMind/tests/test_dep_graph_incremental.py | 2 +- CoderMind/tests/test_e2e.py | 22 +- CoderMind/tests/test_encode_commands.py | 44 +- .../tests/test_encoder_workspace_layout.py | 18 +- CoderMind/tests/test_hooks_install.py | 238 +++--- CoderMind/tests/test_initial_encode_prompt.py | 104 +-- CoderMind/tests/test_integration.py | 8 +- CoderMind/tests/test_rpg_git_meta.py | 2 +- CoderMind/tests/test_rpg_io.py | 6 +- CoderMind/tests/test_rpg_models.py | 6 +- CoderMind/tests/test_rpg_service_path_conv.py | 6 +- CoderMind/tests/test_step3_polish.py | 72 +- CoderMind/tests/test_step4_integration.py | 4 +- CoderMind/tests/test_storage.py | 48 +- CoderMind/tests/test_sync_from_commit_diff.py | 14 +- CoderMind/tests/test_workflow_integration.py | 172 ++--- .../tests/test_workspace_unified_layout.py | 12 +- CoderMind/utils/build_dep_graph.py | 6 +- CoderMind/utils/rpg_stats.py | 22 +- README.md | 28 +- ...d_graph.png => cmind_visualized_graph.png} | Bin 136 files changed, 2033 insertions(+), 2034 deletions(-) rename .github/workflows/{rpgkit-lint.yml => cmind-lint.yml} (75%) rename .github/workflows/{rpgkit-pre-release.yml => cmind-pre-release.yml} (56%) rename .github/workflows/{rpgkit-release.yml => cmind-release.yml} (56%) rename .github/workflows/scripts/{rpgkit => cmind}/check-release-exists.sh (100%) rename .github/workflows/scripts/{rpgkit => cmind}/create-github-release.sh (86%) rename .github/workflows/scripts/{rpgkit => cmind}/create-release-packages.ps1 (91%) rename .github/workflows/scripts/{rpgkit => cmind}/create-release-packages.sh (90%) rename .github/workflows/scripts/{rpgkit => cmind}/generate-release-notes.sh (77%) rename .github/workflows/scripts/{rpgkit => cmind}/get-next-pre-version.sh (91%) rename .github/workflows/scripts/{rpgkit => cmind}/get-next-version.sh (92%) rename .github/workflows/scripts/{rpgkit => cmind}/update-version.sh (95%) rename CoderMind/src/{rpgkit_cli => cmind_cli}/__init__.py (89%) rename CoderMind/src/{rpgkit_cli => cmind_cli}/_assets.py (84%) rename CoderMind/src/{rpgkit_cli => cmind_cli}/_inner_git.py (89%) rename CoderMind/src/{rpgkit_cli => cmind_cli}/_storage.py (87%) rename CoderMind/src/{rpgkit_cli => cmind_cli}/entries.py (76%) rename docs/{rpgkit_visualized_graph.png => cmind_visualized_graph.png} (100%) diff --git a/.github/workflows/rpgkit-lint.yml b/.github/workflows/cmind-lint.yml similarity index 75% rename from .github/workflows/rpgkit-lint.yml rename to .github/workflows/cmind-lint.yml index 8350f79..e91cb63 100644 --- a/.github/workflows/rpgkit-lint.yml +++ b/.github/workflows/cmind-lint.yml @@ -8,14 +8,14 @@ on: branches: [main] paths: - "CoderMind/**" - - ".github/workflows/rpgkit-*.yml" - - ".github/workflows/scripts/rpgkit/**" + - ".github/workflows/cmind-*.yml" + - ".github/workflows/scripts/cmind/**" - ".markdownlint-cli2.jsonc" pull_request: paths: - "CoderMind/**" - - ".github/workflows/rpgkit-*.yml" - - ".github/workflows/scripts/rpgkit/**" + - ".github/workflows/cmind-*.yml" + - ".github/workflows/scripts/cmind/**" - ".markdownlint-cli2.jsonc" workflow_dispatch: diff --git a/.github/workflows/rpgkit-pre-release.yml b/.github/workflows/cmind-pre-release.yml similarity index 56% rename from .github/workflows/rpgkit-pre-release.yml rename to .github/workflows/cmind-pre-release.yml index 768cff9..b1ccf42 100644 --- a/.github/workflows/rpgkit-pre-release.yml +++ b/.github/workflows/cmind-pre-release.yml @@ -6,8 +6,8 @@ on: - dev paths: - "CoderMind/**" - - ".github/workflows/rpgkit-pre-release.yml" - - ".github/workflows/scripts/rpgkit/**" + - ".github/workflows/cmind-pre-release.yml" + - ".github/workflows/scripts/cmind/**" workflow_dispatch: jobs: @@ -26,28 +26,28 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Prepare scripts - run: chmod +x .github/workflows/scripts/rpgkit/*.sh + run: chmod +x .github/workflows/scripts/cmind/*.sh - name: Get CoderMind pre-release version id: get_tag - run: .github/workflows/scripts/rpgkit/get-next-pre-version.sh "${{ github.run_number }}" + run: .github/workflows/scripts/cmind/get-next-pre-version.sh "${{ github.run_number }}" - name: Check if release already exists id: check_release - run: .github/workflows/scripts/rpgkit/check-release-exists.sh "${{ steps.get_tag.outputs.tag_name }}" + run: .github/workflows/scripts/cmind/check-release-exists.sh "${{ steps.get_tag.outputs.tag_name }}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create release package variants if: steps.check_release.outputs.exists == 'false' - run: .github/workflows/scripts/rpgkit/create-release-packages.sh "${{ steps.get_tag.outputs.new_version }}" + run: .github/workflows/scripts/cmind/create-release-packages.sh "${{ steps.get_tag.outputs.new_version }}" - name: Generate release notes if: steps.check_release.outputs.exists == 'false' - run: .github/workflows/scripts/rpgkit/generate-release-notes.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.latest_tag }}" pre + run: .github/workflows/scripts/cmind/generate-release-notes.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.latest_tag }}" pre - name: Create GitHub pre-release if: steps.check_release.outputs.exists == 'false' - run: .github/workflows/scripts/rpgkit/create-github-release.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.tag_name }}" pre + run: .github/workflows/scripts/cmind/create-github-release.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.tag_name }}" pre env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/rpgkit-release.yml b/.github/workflows/cmind-release.yml similarity index 56% rename from .github/workflows/rpgkit-release.yml rename to .github/workflows/cmind-release.yml index 7adea7b..246c455 100644 --- a/.github/workflows/rpgkit-release.yml +++ b/.github/workflows/cmind-release.yml @@ -5,8 +5,8 @@ on: branches: [main] paths: - "CoderMind/**" - - ".github/workflows/rpgkit-release.yml" - - ".github/workflows/scripts/rpgkit/**" + - ".github/workflows/cmind-release.yml" + - ".github/workflows/scripts/cmind/**" workflow_dispatch: jobs: @@ -25,32 +25,32 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Prepare scripts - run: chmod +x .github/workflows/scripts/rpgkit/*.sh + run: chmod +x .github/workflows/scripts/cmind/*.sh - name: Get next CoderMind version id: get_tag - run: .github/workflows/scripts/rpgkit/get-next-version.sh + run: .github/workflows/scripts/cmind/get-next-version.sh - name: Check if release already exists id: check_release - run: .github/workflows/scripts/rpgkit/check-release-exists.sh "${{ steps.get_tag.outputs.tag_name }}" + run: .github/workflows/scripts/cmind/check-release-exists.sh "${{ steps.get_tag.outputs.tag_name }}" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Update version in pyproject.toml if: steps.check_release.outputs.exists == 'false' - run: .github/workflows/scripts/rpgkit/update-version.sh "${{ steps.get_tag.outputs.new_version }}" + run: .github/workflows/scripts/cmind/update-version.sh "${{ steps.get_tag.outputs.new_version }}" - name: Create release package variants if: steps.check_release.outputs.exists == 'false' - run: .github/workflows/scripts/rpgkit/create-release-packages.sh "${{ steps.get_tag.outputs.new_version }}" + run: .github/workflows/scripts/cmind/create-release-packages.sh "${{ steps.get_tag.outputs.new_version }}" - name: Generate release notes if: steps.check_release.outputs.exists == 'false' - run: .github/workflows/scripts/rpgkit/generate-release-notes.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.latest_tag }}" stable + run: .github/workflows/scripts/cmind/generate-release-notes.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.latest_tag }}" stable - name: Create GitHub release if: steps.check_release.outputs.exists == 'false' - run: .github/workflows/scripts/rpgkit/create-github-release.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.tag_name }}" stable + run: .github/workflows/scripts/cmind/create-github-release.sh "${{ steps.get_tag.outputs.new_version }}" "${{ steps.get_tag.outputs.tag_name }}" stable env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/scripts/rpgkit/check-release-exists.sh b/.github/workflows/scripts/cmind/check-release-exists.sh similarity index 100% rename from .github/workflows/scripts/rpgkit/check-release-exists.sh rename to .github/workflows/scripts/cmind/check-release-exists.sh diff --git a/.github/workflows/scripts/rpgkit/create-github-release.sh b/.github/workflows/scripts/cmind/create-github-release.sh similarity index 86% rename from .github/workflows/scripts/rpgkit/create-github-release.sh rename to .github/workflows/scripts/cmind/create-github-release.sh index 7fc3cd5..6d134e7 100755 --- a/.github/workflows/scripts/rpgkit/create-github-release.sh +++ b/.github/workflows/scripts/cmind/create-github-release.sh @@ -11,12 +11,12 @@ TAG_NAME="$2" RELEASE_KIND="${3:-stable}" VERSION_NO_V="${VERSION#v}" REPO_ROOT="${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}" -PROJECT_DIR="${PROJECT_DIR:-RPG-Kit}" +PROJECT_DIR="${PROJECT_DIR:-CoderMind}" PROJECT_ROOT="$REPO_ROOT/$PROJECT_DIR" GENRELEASES_DIR="$PROJECT_ROOT/.genreleases" NOTES_FILE="${NOTES_FILE:-$REPO_ROOT/release_notes.md}" -mapfile -t ASSETS < <(find "$GENRELEASES_DIR" -maxdepth 1 -type f -name "rpgkit-template-*-${VERSION}.zip" | sort) +mapfile -t ASSETS < <(find "$GENRELEASES_DIR" -maxdepth 1 -type f -name "cmind-template-*-${VERSION}.zip" | sort) if [[ ${#ASSETS[@]} -eq 0 ]]; then echo "No release assets found in $GENRELEASES_DIR for $VERSION" >&2 exit 1 @@ -34,7 +34,7 @@ fi gh release create "$TAG_NAME" \ "${ASSETS[@]}" \ - --title "RPG-Kit Templates - $VERSION_NO_V" \ + --title "CoderMind Templates - $VERSION_NO_V" \ --notes-file "$NOTES_FILE" \ "${PRERELEASE_ARG[@]}" \ "${TARGET_ARG[@]}" diff --git a/.github/workflows/scripts/rpgkit/create-release-packages.ps1 b/.github/workflows/scripts/cmind/create-release-packages.ps1 similarity index 91% rename from .github/workflows/scripts/rpgkit/create-release-packages.ps1 rename to .github/workflows/scripts/cmind/create-release-packages.ps1 index 866a946..f2f45b9 100755 --- a/.github/workflows/scripts/rpgkit/create-release-packages.ps1 +++ b/.github/workflows/scripts/cmind/create-release-packages.ps1 @@ -49,10 +49,10 @@ if ($Version -notmatch '^v\d+\.\d+\.\d+(-.+)?$') { } $RepoRoot = if ($env:GITHUB_WORKSPACE) { $env:GITHUB_WORKSPACE } else { (git rev-parse --show-toplevel).Trim() } -$ProjectDir = if ($env:PROJECT_DIR) { $env:PROJECT_DIR } else { "RPG-Kit" } +$ProjectDir = if ($env:PROJECT_DIR) { $env:PROJECT_DIR } else { "CoderMind" } $ProjectRoot = Join-Path $RepoRoot $ProjectDir if (-not (Test-Path $ProjectRoot)) { - Write-Error "RPG-Kit project directory not found: $ProjectRoot" + Write-Error "CoderMind project directory not found: $ProjectRoot" exit 1 } Set-Location $ProjectRoot @@ -68,10 +68,10 @@ New-Item -ItemType Directory -Path $GenReleasesDir -Force | Out-Null function Rewrite-Paths { param([string]$Content) - $Content = $Content -replace '(/?)\bmemory/', '.rpgkit/memory/' - $Content = $Content -replace '(/?)\bscripts/', '.rpgkit/scripts/' - $Content = $Content -replace '(/?)\btemplates/', '.rpgkit/templates/' - $Content = $Content -replace '(/?)\butils/', '.rpgkit/utils/' + $Content = $Content -replace '(/?)\bmemory/', '.cmind/memory/' + $Content = $Content -replace '(/?)\bscripts/', '.cmind/scripts/' + $Content = $Content -replace '(/?)\btemplates/', '.cmind/templates/' + $Content = $Content -replace '(/?)\butils/', '.cmind/utils/' return $Content } @@ -97,11 +97,11 @@ function Generate-Commands { $description = $matches[1] } - # Rewrite paths for .rpgkit structure + # Rewrite paths for .cmind structure $body = Rewrite-Paths -Content $body # Generate output file based on extension - $outputFile = Join-Path $OutputDir "rpgkit.$name.$Extension" + $outputFile = Join-Path $OutputDir "cmind.$name.$Extension" switch ($Extension) { 'toml' { @@ -127,7 +127,7 @@ function Generate-CopilotPrompts { New-Item -ItemType Directory -Path $PromptsDir -Force | Out-Null - $agentFiles = Get-ChildItem -Path "$AgentsDir/rpgkit.*.agent.md" -File -ErrorAction SilentlyContinue + $agentFiles = Get-ChildItem -Path "$AgentsDir/cmind.*.agent.md" -File -ErrorAction SilentlyContinue foreach ($agentFile in $agentFiles) { $basename = $agentFile.Name -replace '\.agent\.md$', '' @@ -153,18 +153,18 @@ function Build-Variant { New-Item -ItemType Directory -Path $baseDir -Force | Out-Null # Copy base structure but filter scripts by variant - $specDir = Join-Path $baseDir ".rpgkit" + $specDir = Join-Path $baseDir ".cmind" New-Item -ItemType Directory -Path $specDir -Force | Out-Null if (Test-Path "pyproject.toml") { Copy-Item -Path "pyproject.toml" -Destination (Join-Path $specDir "pyproject.toml") -Force - Write-Host "Copied pyproject.toml -> .rpgkit" + Write-Host "Copied pyproject.toml -> .cmind" } # Copy memory directory if (Test-Path "memory") { Copy-Item -Path "memory" -Destination $specDir -Recurse -Force - Write-Host "Copied memory -> .rpgkit" + Write-Host "Copied memory -> .cmind" } # Only copy the relevant script variant directory @@ -176,13 +176,13 @@ function Build-Variant { 'sh' { if (Test-Path "scripts/bash") { Copy-Item -Path "scripts/bash" -Destination $scriptsDestDir -Recurse -Force - Write-Host "Copied scripts/bash -> .rpgkit/scripts" + Write-Host "Copied scripts/bash -> .cmind/scripts" } } 'ps' { if (Test-Path "scripts/powershell") { Copy-Item -Path "scripts/powershell" -Destination $scriptsDestDir -Recurse -Force - Write-Host "Copied scripts/powershell -> .rpgkit/scripts" + Write-Host "Copied scripts/powershell -> .cmind/scripts" } } } @@ -212,13 +212,13 @@ function Build-Variant { New-Item -ItemType Directory -Path $destFileDir -Force | Out-Null Copy-Item -Path $_.FullName -Destination $destFile -Force } - Write-Host "Copied templates -> .rpgkit/templates" + Write-Host "Copied templates -> .cmind/templates" } # Copy utils directory if (Test-Path "utils") { Copy-Item -Path "utils" -Destination $specDir -Recurse -Force - Write-Host "Copied utils -> .rpgkit/utils" + Write-Host "Copied utils -> .cmind/utils" } # Replace placeholder in copied scripts with the actual CLI command name @@ -342,7 +342,7 @@ function Build-Variant { } # Create zip archive - $zipFile = Join-Path $GenReleasesDir "rpgkit-template-${Agent}-${Script}-${Version}.zip" + $zipFile = Join-Path $GenReleasesDir "cmind-template-${Agent}-${Script}-${Version}.zip" Compress-Archive -Path "$baseDir/*" -DestinationPath $zipFile -Force Write-Host "Created $zipFile" } @@ -411,6 +411,6 @@ foreach ($agent in $AgentList) { } Write-Host "`nArchives in ${GenReleasesDir}:" -Get-ChildItem -Path $GenReleasesDir -Filter "rpgkit-template-*-${Version}.zip" | ForEach-Object { +Get-ChildItem -Path $GenReleasesDir -Filter "cmind-template-*-${Version}.zip" | ForEach-Object { Write-Host " $($_.Name)" } \ No newline at end of file diff --git a/.github/workflows/scripts/rpgkit/create-release-packages.sh b/.github/workflows/scripts/cmind/create-release-packages.sh similarity index 90% rename from .github/workflows/scripts/rpgkit/create-release-packages.sh rename to .github/workflows/scripts/cmind/create-release-packages.sh index 1c519ce..431f55b 100755 --- a/.github/workflows/scripts/rpgkit/create-release-packages.sh +++ b/.github/workflows/scripts/cmind/create-release-packages.sh @@ -25,12 +25,12 @@ if [[ ! $NEW_VERSION =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.+)?$ ]]; then fi REPO_ROOT="${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}" -PROJECT_DIR="${PROJECT_DIR:-RPG-Kit}" +PROJECT_DIR="${PROJECT_DIR:-CoderMind}" PROJECT_ROOT="$REPO_ROOT/$PROJECT_DIR" GENRELEASES_DIR="$PROJECT_ROOT/.genreleases" if [[ ! -d "$PROJECT_ROOT" ]]; then - echo "RPG-Kit project directory not found: $PROJECT_ROOT" >&2 + echo "CoderMind project directory not found: $PROJECT_ROOT" >&2 exit 1 fi @@ -57,11 +57,11 @@ generate_commands() { case $ext in toml) body=$(sed 's/\\/\\\\/g' <<< "$body") - { echo "description = \"$description\""; echo; echo "prompt = \"\"\""; echo "$body"; echo "\"\"\""; } > "$output_dir/rpgkit.$name.$ext" ;; + { echo "description = \"$description\""; echo; echo "prompt = \"\"\""; echo "$body"; echo "\"\"\""; } > "$output_dir/cmind.$name.$ext" ;; md) - echo "$body" > "$output_dir/rpgkit.$name.$ext" ;; + echo "$body" > "$output_dir/cmind.$name.$ext" ;; agent.md) - echo "$body" > "$output_dir/rpgkit.$name.$ext" ;; + echo "$body" > "$output_dir/cmind.$name.$ext" ;; esac done } @@ -71,7 +71,7 @@ generate_copilot_prompts() { mkdir -p "$prompts_dir" # Generate a .prompt.md file for each .agent.md file - for agent_file in "$agents_dir"/rpgkit.*.agent.md; do + for agent_file in "$agents_dir"/cmind.*.agent.md; do [[ -f "$agent_file" ]] || continue local basename=$(basename "$agent_file" .agent.md) @@ -109,27 +109,27 @@ build_variant() { mkdir -p "$base_dir" # Copy base structure but filter scripts by variant - SPEC_DIR="$base_dir/.rpgkit" + SPEC_DIR="$base_dir/.cmind" mkdir -p "$SPEC_DIR" # Create empty data directory for runtime output mkdir -p "$SPEC_DIR/data" - [[ -f pyproject.toml ]] && { cp pyproject.toml "$SPEC_DIR/pyproject.toml"; echo "Copied pyproject.toml -> .rpgkit"; } + [[ -f pyproject.toml ]] && { cp pyproject.toml "$SPEC_DIR/pyproject.toml"; echo "Copied pyproject.toml -> .cmind"; } - [[ -d memory ]] && { cp -r memory "$SPEC_DIR/"; echo "Copied memory -> .rpgkit"; } + [[ -d memory ]] && { cp -r memory "$SPEC_DIR/"; echo "Copied memory -> .cmind"; } # Only copy the relevant script variant directory if [[ -d scripts ]]; then mkdir -p "$SPEC_DIR/scripts" case $script in sh) - [[ -d scripts/bash ]] && { cp -r scripts/bash "$SPEC_DIR/scripts/"; echo "Copied scripts/bash -> .rpgkit/scripts"; } + [[ -d scripts/bash ]] && { cp -r scripts/bash "$SPEC_DIR/scripts/"; echo "Copied scripts/bash -> .cmind/scripts"; } # Copy any script files that aren't in variant-specific directories find scripts -maxdepth 1 -type f -exec cp {} "$SPEC_DIR/scripts/" \; 2>/dev/null || true ;; ps) - [[ -d scripts/powershell ]] && { cp -r scripts/powershell "$SPEC_DIR/scripts/"; echo "Copied scripts/powershell -> .rpgkit/scripts"; } + [[ -d scripts/powershell ]] && { cp -r scripts/powershell "$SPEC_DIR/scripts/"; echo "Copied scripts/powershell -> .cmind/scripts"; } # Copy any script files that aren't in variant-specific directories find scripts -maxdepth 1 -type f -exec cp {} "$SPEC_DIR/scripts/" \; 2>/dev/null || true ;; @@ -178,9 +178,9 @@ build_variant() { fi fi - [[ -d templates ]] && { mkdir -p "$SPEC_DIR/templates"; find templates -type f -not -path "templates/commands/*" -not -name "vscode-settings.json" -exec cp --parents {} "$SPEC_DIR"/ \; ; echo "Copied templates -> .rpgkit/templates"; } + [[ -d templates ]] && { mkdir -p "$SPEC_DIR/templates"; find templates -type f -not -path "templates/commands/*" -not -name "vscode-settings.json" -exec cp --parents {} "$SPEC_DIR"/ \; ; echo "Copied templates -> .cmind/templates"; } - [[ -d utils ]] && { cp -r utils "$SPEC_DIR/"; echo "Copied utils -> .rpgkit/utils"; } + [[ -d utils ]] && { cp -r utils "$SPEC_DIR/"; echo "Copied utils -> .cmind/utils"; } case $agent in claude) @@ -245,8 +245,8 @@ SETTINGS mkdir -p "$base_dir/.agents/commands" generate_commands md "$base_dir/.agents/commands" ;; esac - create_archive "$base_dir" "$GENRELEASES_DIR/rpgkit-template-${agent}-${script}-${NEW_VERSION}.zip" - echo "Created $GENRELEASES_DIR/rpgkit-template-${agent}-${script}-${NEW_VERSION}.zip" + create_archive "$base_dir" "$GENRELEASES_DIR/cmind-template-${agent}-${script}-${NEW_VERSION}.zip" + echo "Created $GENRELEASES_DIR/cmind-template-${agent}-${script}-${NEW_VERSION}.zip" } # Determine agent list @@ -296,5 +296,5 @@ for agent in "${AGENT_LIST[@]}"; do done echo "Archives in $GENRELEASES_DIR:" -ls -1 "$GENRELEASES_DIR"/rpgkit-template-*-"${NEW_VERSION}".zip +ls -1 "$GENRELEASES_DIR"/cmind-template-*-"${NEW_VERSION}".zip diff --git a/.github/workflows/scripts/rpgkit/generate-release-notes.sh b/.github/workflows/scripts/cmind/generate-release-notes.sh similarity index 77% rename from .github/workflows/scripts/rpgkit/generate-release-notes.sh rename to .github/workflows/scripts/cmind/generate-release-notes.sh index 0ee3fac..b9a84ad 100755 --- a/.github/workflows/scripts/rpgkit/generate-release-notes.sh +++ b/.github/workflows/scripts/cmind/generate-release-notes.sh @@ -10,7 +10,7 @@ NEW_VERSION="$1" LAST_TAG="$2" RELEASE_KIND="${3:-stable}" REPO_ROOT="${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}" -PROJECT_DIR="${PROJECT_DIR:-RPG-Kit}" +PROJECT_DIR="${PROJECT_DIR:-CoderMind}" NOTES_FILE="${NOTES_FILE:-$REPO_ROOT/release_notes.md}" if git rev-parse -q --verify "refs/tags/$LAST_TAG" >/dev/null; then @@ -19,13 +19,13 @@ else COMMITS=$(git log --oneline --pretty=format:"- %s" HEAD -- "$PROJECT_DIR" | head -n 10 || true) fi -COMMITS="${COMMITS:-No RPG-Kit changes found.}" +COMMITS="${COMMITS:-No CoderMind changes found.}" if [[ "$RELEASE_KIND" == "pre" ]]; then BRANCH="${GITHUB_REF_NAME:-unknown}" cat > "$NOTES_FILE" << EOF > **This is a development pre-release from the \`$BRANCH\` branch.** -> It is intended for testing purposes only. For stable releases, use \`rpgkit init\` without \`--pre\`. +> It is intended for testing purposes only. For stable releases, use \`cmind init\` without \`--pre\`. ## Changelog (since ${LAST_TAG}) @@ -33,7 +33,7 @@ $COMMITS EOF else cat > "$NOTES_FILE" << EOF -This is the latest RPG-Kit template release. We recommend using the RPG-Kit CLI to scaffold projects, but the template archives can also be downloaded and managed manually. +This is the latest CoderMind template release. We recommend using the CoderMind CLI to scaffold projects, but the template archives can also be downloaded and managed manually. ## Changelog (since ${LAST_TAG}) diff --git a/.github/workflows/scripts/rpgkit/get-next-pre-version.sh b/.github/workflows/scripts/cmind/get-next-pre-version.sh similarity index 91% rename from .github/workflows/scripts/rpgkit/get-next-pre-version.sh rename to .github/workflows/scripts/cmind/get-next-pre-version.sh index 1dbc296..aa3d272 100755 --- a/.github/workflows/scripts/rpgkit/get-next-pre-version.sh +++ b/.github/workflows/scripts/cmind/get-next-pre-version.sh @@ -7,7 +7,7 @@ if [[ $# -ne 1 ]]; then fi RUN_NUMBER="$1" -TAG_PREFIX="${TAG_PREFIX:-rpgkit-v}" +TAG_PREFIX="${TAG_PREFIX:-cmind-v}" INITIAL_VERSION="${INITIAL_VERSION:-0.1.0}" write_output() { @@ -31,6 +31,6 @@ TAG_NAME="${TAG_PREFIX}${NEW_VERSION#v}" write_output "new_version=$NEW_VERSION" write_output "tag_name=$TAG_NAME" -echo "Latest stable RPG-Kit tag: $LATEST_TAG" +echo "Latest stable CoderMind tag: $LATEST_TAG" echo "Pre-release version will be: $NEW_VERSION" echo "Pre-release tag will be: $TAG_NAME" diff --git a/.github/workflows/scripts/rpgkit/get-next-version.sh b/.github/workflows/scripts/cmind/get-next-version.sh similarity index 92% rename from .github/workflows/scripts/rpgkit/get-next-version.sh rename to .github/workflows/scripts/cmind/get-next-version.sh index d6687eb..6840061 100755 --- a/.github/workflows/scripts/rpgkit/get-next-version.sh +++ b/.github/workflows/scripts/cmind/get-next-version.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -euo pipefail -TAG_PREFIX="${TAG_PREFIX:-rpgkit-v}" +TAG_PREFIX="${TAG_PREFIX:-cmind-v}" write_output() { [[ -n "${GITHUB_OUTPUT:-}" ]] && echo "$1" >> "$GITHUB_OUTPUT" @@ -32,6 +32,6 @@ TAG_NAME="${TAG_PREFIX}${NEW_VERSION#v}" write_output "new_version=$NEW_VERSION" write_output "tag_name=$TAG_NAME" -echo "Latest RPG-Kit tag: $LATEST_TAG" +echo "Latest CoderMind tag: $LATEST_TAG" echo "New version will be: $NEW_VERSION" echo "Release tag will be: $TAG_NAME" diff --git a/.github/workflows/scripts/rpgkit/update-version.sh b/.github/workflows/scripts/cmind/update-version.sh similarity index 95% rename from .github/workflows/scripts/rpgkit/update-version.sh rename to .github/workflows/scripts/cmind/update-version.sh index 128bae1..b26be54 100755 --- a/.github/workflows/scripts/rpgkit/update-version.sh +++ b/.github/workflows/scripts/cmind/update-version.sh @@ -9,7 +9,7 @@ fi VERSION="$1" PYTHON_VERSION="${VERSION#v}" REPO_ROOT="${GITHUB_WORKSPACE:-$(git rev-parse --show-toplevel)}" -PROJECT_DIR="${PROJECT_DIR:-RPG-Kit}" +PROJECT_DIR="${PROJECT_DIR:-CoderMind}" PROJECT_ROOT="$REPO_ROOT/$PROJECT_DIR" PYPROJECT="$PROJECT_ROOT/pyproject.toml" diff --git a/.gitignore b/.gitignore index 878121c..e57d445 100644 --- a/.gitignore +++ b/.gitignore @@ -417,7 +417,7 @@ FodyWeavers.xsd *.msm *.msp -# RPG-Kit release artifacts -RPG-Kit/.genreleases/ +# CoderMind release artifacts +CoderMind/.genreleases/ release_notes.md workspace/ diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc index ab2b9e9..89c4f60 100644 --- a/.markdownlint-cli2.jsonc +++ b/.markdownlint-cli2.jsonc @@ -22,8 +22,8 @@ } }, "ignores": [ - "RPG-Kit/.genreleases/", - "RPG-Kit/.pytest_cache/", - "RPG-Kit/**/__pycache__/" + "CoderMind/.genreleases/", + "CoderMind/.pytest_cache/", + "CoderMind/**/__pycache__/" ] } diff --git a/CoderMind/.gitignore b/CoderMind/.gitignore index 3bcc672..df54387 100644 --- a/CoderMind/.gitignore +++ b/CoderMind/.gitignore @@ -4,9 +4,9 @@ __pycache__/ *.py[cod] *$py.class -# --- RPG-Kit generated data & temp --- -.rpgkit/data/ -.rpgkit/tmp/ +# --- CoderMind generated data & temp --- +.cmind/data/ +.cmind/tmp/ # --- Logs --- *.log @@ -16,7 +16,7 @@ venv/ .venv/ .venv_dev/ /env/ -.rpgkit_dev_env/ +.cmind_dev_env/ # --- IDE --- .idea/ @@ -221,14 +221,14 @@ __marimo__/ # Planning workspace*/ plans/ -# --- RPG-Kit workspace symlinks --- +# --- CoderMind workspace symlinks --- .claude -# RPG-Kit ignores (managed by `rpgkit init/update`) -.rpgkit/ +# CoderMind ignores (managed by `cmind init/update`) +.cmind/ # But DO commit the workspace AI config so collaborators get a sane default. # Plan: plans/01-package-bundle-and-ai-config.md decision 15. -!.rpgkit/config.toml +!.cmind/config.toml .vscode/mcp.json .vscode/tasks.json .mcp.json diff --git a/CoderMind/.markdownlint-cli2.jsonc b/CoderMind/.markdownlint-cli2.jsonc index 27f3ac6..a0adb96 100644 --- a/CoderMind/.markdownlint-cli2.jsonc +++ b/CoderMind/.markdownlint-cli2.jsonc @@ -1,6 +1,6 @@ { // Mirror of the workspace-root `.markdownlint-cli2.jsonc` so running - // `markdownlint-cli2` from `RPG-Kit/` picks up the same rules. + // `markdownlint-cli2` from `CoderMind/` picks up the same rules. // The slash-command templates under `templates/commands/` are prompt // material consumed verbatim by Coding Agents — wrapping at 80 cols // or forcing an H1 would damage their semantics, so the corresponding @@ -31,7 +31,7 @@ // Internal design notes / WIP plans — not user-facing docs. "plans/", // The entire workspace/ tree is for e2e fixtures + backups; not - // part of rpgkit's published docs. + // part of cmind's published docs. "workspace/" ] } diff --git a/CoderMind/README.hi-IN.md b/CoderMind/README.hi-IN.md index 86b24fc..77855d0 100644 --- a/CoderMind/README.hi-IN.md +++ b/CoderMind/README.hi-IN.md @@ -1,4 +1,4 @@ -

RPG-Kit

+

CoderMind

English | @@ -12,9 +12,9 @@ कोडिंग एजेंट्स लोकल संपादन में मजबूत होते हैं, लेकिन एक स्थिर प्लानिंग संरचना के बिना रिपॉज़िटरी-स्तर के कार्य अक्सर विफल हो जाते हैं। आवश्यकताएँ बहक जाती हैं, आर्किटेक्चर के निर्णय खो जाते हैं, मल्टी-फ़ाइल जनरेशन असंगत हो जाती है, और अपडेट छिपी हुई dependencies को मिस कर सकते हैं। -RPG-Kit, Claude Code और GitHub Copilot को रिपॉज़िटरी-स्तर कोडिंग के लिए एक **persistent RPG workspace** देता है। यह वर्कस्पेस एक **Repository Planning Graph (RPG)** के चारों ओर बना है, जो आवश्यकताओं, features, आर्किटेक्चर, फ़ाइलों, कोड entities और dependencies को जोड़ता है। +CoderMind, Claude Code और GitHub Copilot को रिपॉज़िटरी-स्तर कोडिंग के लिए एक **persistent RPG workspace** देता है। यह वर्कस्पेस एक **Repository Planning Graph (RPG)** के चारों ओर बना है, जो आवश्यकताओं, features, आर्किटेक्चर, फ़ाइलों, कोड entities और dependencies को जोड़ता है। -RPG-Kit के साथ, एजेंट्स ग्राफ-संचालित वर्कफ़्लो के माध्यम से काम करते हैं: +CoderMind के साथ, एजेंट्स ग्राफ-संचालित वर्कफ़्लो के माध्यम से काम करते हैं: - **Build (निर्माण)**: आवश्यकताओं को RPG प्लान में बदलें, फिर एक मल्टी-फ़ाइल रिपॉज़िटरी बनाएँ। - **Understand (समझें)**: किसी मौजूदा रिपॉज़िटरी को RPG में मैप करें, फिर खोजें, अन्वेषण करें और समझाएँ। @@ -77,11 +77,11 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree -### RPG-Kit वास्तविक उपयोग में +### CoderMind वास्तविक उपयोग में -नीचे दी गई छवि इस रिपॉज़िटरी के लिए जनरेट किए गए ग्राफ़ विज़ुअलाइज़ेशन का एक भाग है। `/rpgkit.encode` चलाने के बाद, पूर्ण इंटरैक्टिव ग्राफ़ देखने के लिए `/.rpgkit/reports/rpg.html` खोलें। वर्तमान वर्कस्पेस के हल किए गए पथ देखने के लिए `rpgkit version` चलाएँ। +नीचे दी गई छवि इस रिपॉज़िटरी के लिए जनरेट किए गए ग्राफ़ विज़ुअलाइज़ेशन का एक भाग है। `/cmind.encode` चलाने के बाद, पूर्ण इंटरैक्टिव ग्राफ़ देखने के लिए `/.cmind/reports/rpg.html` खोलें। वर्तमान वर्कस्पेस के हल किए गए पथ देखने के लिए `cmind version` चलाएँ। -![RPG-Kit repository graph visualization](../docs/rpgkit_visualized_graph.png) +![CoderMind repository graph visualization](../docs/cmind_visualized_graph.png) ## इंस्टॉलेशन @@ -92,38 +92,38 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree - Git - एक इंस्टॉल और प्रमाणित AI कोडिंग एजेंट CLI: [GitHub Copilot](https://docs.github.com/en/copilot) या [Claude Code](https://docs.anthropic.com/en/docs/claude-code/setup) -### RPG-Kit इंस्टॉल करें +### CoderMind इंस्टॉल करें ```bash # Persistent इंस्टॉलेशन (अनुशंसित) -uv tool install rpgkit-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" -rpgkit check +uv tool install cmind-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" +cmind check # एक बार के उपयोग के लिए -uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" rpgkit init +uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" cmind init ``` -`0.1.3` से, wheel pipeline scripts और slash-command templates को packaged assets के रूप में शामिल करता है, इसलिए `rpgkit init` ऑफ़लाइन वातावरणों (जैसे air-gapped या corporate proxy वातावरण) में भी काम करता है। +`0.1.3` से, wheel pipeline scripts और slash-command templates को packaged assets के रूप में शामिल करता है, इसलिए `cmind init` ऑफ़लाइन वातावरणों (जैसे air-gapped या corporate proxy वातावरण) में भी काम करता है। ## Quick Start: नई रिपॉज़िटरी -जब आप RPG-Kit से आवश्यकताओं को एक नए कोडबेस में बदलवाना चाहते हैं, तब इस मार्ग का उपयोग करें। +जब आप CoderMind से आवश्यकताओं को एक नए कोडबेस में बदलवाना चाहते हैं, तब इस मार्ग का उपयोग करें। > [!WARNING] -> बहुत अधिक जनरेटेड कोड वाली परियोजनाओं के लिए, `/rpgkit.design_interfaces` और `/rpgkit.code_gen` को चलने में काफ़ी समय लग सकता है। उदाहरण: 100 features में लगभग 30 मिनट लगते हैं। +> बहुत अधिक जनरेटेड कोड वाली परियोजनाओं के लिए, `/cmind.design_interfaces` और `/cmind.code_gen` को चलने में काफ़ी समय लग सकता है। उदाहरण: 100 features में लगभग 30 मिनट लगते हैं। 1. नई परियोजना को आरंभीकृत करें: ```bash - rpgkit init my-project + cmind init my-project cd my-project ``` सामान्य विकल्प: ```bash - rpgkit init my-project --ai claude --script sh - rpgkit init my-project --ai copilot + cmind init my-project --ai claude --script sh + cmind init my-project --ai copilot ``` 2. **[वैकल्पिक]** अपने आवश्यकता दस्तावेज़ `my-project/docs/` में रखें। @@ -133,45 +133,45 @@ uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-K 4. फॉरवर्ड पाइपलाइन चलाएँ: ```text - /rpgkit.feature_spec - /rpgkit.feature_build - /rpgkit.feature_refactor - [Optional] /rpgkit.feature_edit - /rpgkit.build_skeleton - /rpgkit.build_data_flow - /rpgkit.design_base_classes - /rpgkit.design_interfaces - /rpgkit.plan_tasks - /rpgkit.code_gen - [Optional] /rpgkit.rpg_edit + /cmind.feature_spec + /cmind.feature_build + /cmind.feature_refactor + [Optional] /cmind.feature_edit + /cmind.build_skeleton + /cmind.build_data_flow + /cmind.design_base_classes + /cmind.design_interfaces + /cmind.plan_tasks + /cmind.code_gen + [Optional] /cmind.rpg_edit ``` > [!IMPORTANT] > **हर Coding Agent का इनवोकेशन थोड़ा अलग होता है**: > -> - **Claude Code**: चैट में सीधे `/rpgkit.feature_spec ...` टाइप करें — slash command पहचाने जाते हैं और संबंधित workflow ट्रिगर हो जाता है। -> - **GitHub Copilot CLI**: slash command समर्थित नहीं हैं (कस्टम agent समर्थित हैं), इसलिए पहले `/agent rpgkit.feature_spec` से लक्ष्य agent पर स्विच करें, फिर `start` टाइप करके इसका अंतर्निहित workflow चलाएँ। +> - **Claude Code**: चैट में सीधे `/cmind.feature_spec ...` टाइप करें — slash command पहचाने जाते हैं और संबंधित workflow ट्रिगर हो जाता है। +> - **GitHub Copilot CLI**: slash command समर्थित नहीं हैं (कस्टम agent समर्थित हैं), इसलिए पहले `/agent cmind.feature_spec` से लक्ष्य agent पर स्विच करें, फिर `start` टाइप करके इसका अंतर्निहित workflow चलाएँ। -RPG-Kit क्रमिक रूप से `~/.rpgkit/workspaces//data/rpg.json` बनाता है और इसका उपयोग आवश्यकताओं, प्लानिंग आउटपुट, जनरेटेड कोड और dependency जानकारी को संरेखित रखने के लिए करता है। आपके वर्कस्पेस की स्रोत फ़़ाइलें दूषित नहीं होंगी। +CoderMind क्रमिक रूप से `~/.cmind/workspaces//data/rpg.json` बनाता है और इसका उपयोग आवश्यकताओं, प्लानिंग आउटपुट, जनरेटेड कोड और dependency जानकारी को संरेखित रखने के लिए करता है। आपके वर्कस्पेस की स्रोत फ़़ाइलें दूषित नहीं होंगी। ## Quick Start: मौजूदा रिपॉज़िटरी जब आपके पास पहले से एक रिपॉज़िटरी है और आप चाहते हैं कि AI एजेंट इसे RPG कॉन्टेक्स्ट के साथ समझे या संपादित करे, तब इस मार्ग का उपयोग करें। > [!WARNING] -> बड़ी परियोजनाओं के लिए, `rpgkit init . --encode` और `/rpgkit.encode` को चलने में काफ़ी समय लग सकता है। उदाहरण: 200 स्रोत फ़ाइलों में लगभग 100 मिनट लगते हैं। +> बड़ी परियोजनाओं के लिए, `cmind init . --encode` और `/cmind.encode` को चलने में काफ़ी समय लग सकता है। उदाहरण: 200 स्रोत फ़ाइलों में लगभग 100 मिनट लगते हैं। -1. रिपॉज़िटरी रूट में RPG-Kit को आरंभीकृत करें और प्रारंभिक ग्राफ़ बनाएँ: +1. रिपॉज़िटरी रूट में CoderMind को आरंभीकृत करें और प्रारंभिक ग्राफ़ बनाएँ: ```bash cd existing-repo/ - rpgkit init . --encode # --encode वर्तमान कोड से RPG उत्पन्न करता है + cmind init . --encode # --encode वर्तमान कोड से RPG उत्पन्न करता है ``` यदि आप गैर-खाली निर्देशिका के लिए पुष्टि संकेत को छोड़ना चाहते हैं: ```bash - rpgkit init . --force --encode + cmind init . --force --encode ``` 2. रिपॉज़िटरी में अपना AI कोडिंग एजेंट लॉन्च करें। @@ -179,39 +179,39 @@ RPG-Kit क्रमिक रूप से `~/.rpgkit/workspaces/ 3. **[वैकल्पिक]** MCP टूल्स और स्लैश कमांड्स के माध्यम से जनरेटेड RPG का उपयोग करें। नीचे दिए गए कमांड केवल मैन्युअल रूप से चलाने पर आवश्यक हैं: ```text - /rpgkit.encode # आवश्यकता पड़ने पर पूर्ण RPG को पुनर्निर्मित करें - /rpgkit.update_rpg # मैन्युअल वृद्धिशील अपडेट (fallback) - /rpgkit.rpg_edit # ग्राफ़-जागरूक कोड संपादन + /cmind.encode # आवश्यकता पड़ने पर पूर्ण RPG को पुनर्निर्मित करें + /cmind.update_rpg # मैन्युअल वृद्धिशील अपडेट (fallback) + /cmind.rpg_edit # ग्राफ़-जागरूक कोड संपादन ``` -4. हर commit के बाद, RPG-Kit द्वारा इंस्टॉल किया गया git hook स्वचालित रूप से `rpgkit hook ` dispatcher को कॉल करता है, RPG को अपडेट करता है और उसे कोड परिवर्तनों के साथ संरेखित रखता है। यदि hook विफल हो जाता है या छोड़ दिया जाता है, तो `/rpgkit.update_rpg` मैन्युअल रूप से चलाएँ। +4. हर commit के बाद, CoderMind द्वारा इंस्टॉल किया गया git hook स्वचालित रूप से `cmind hook ` dispatcher को कॉल करता है, RPG को अपडेट करता है और उसे कोड परिवर्तनों के साथ संरेखित रखता है। यदि hook विफल हो जाता है या छोड़ दिया जाता है, तो `/cmind.update_rpg` मैन्युअल रूप से चलाएँ। -## `rpgkit init` के बाद क्या होता है +## `cmind init` के बाद क्या होता है -`rpgkit init` आपकी स्रोत फ़़ाइलों को संशोधित नहीं करता है, **और आपके वर्कस्पेस में रनटाइम स्टेट नहीं लिखता है**। यह आपके वर्कस्पेस में केवल command definitions, MCP कॉन्फ़़िगरेशन और hooks जोड़ता है। RPG-Kit का रनटाइम डेटा (outputs और logs) home-side निर्देशिका `~/.rpgkit/workspaces//` के अंतर्गत रखा जाता है, जहाँ `` वर्कस्पेस के absolute path से जनित एक पठनीय slug है (उदाहरण: `home-hys-projects-myrepo`)। +`cmind init` आपकी स्रोत फ़़ाइलों को संशोधित नहीं करता है, **और आपके वर्कस्पेस में रनटाइम स्टेट नहीं लिखता है**। यह आपके वर्कस्पेस में केवल command definitions, MCP कॉन्फ़़िगरेशन और hooks जोड़ता है। CoderMind का रनटाइम डेटा (outputs और logs) home-side निर्देशिका `~/.cmind/workspaces//` के अंतर्गत रखा जाता है, जहाँ `` वर्कस्पेस के absolute path से जनित एक पठनीय slug है (उदाहरण: `home-hys-projects-myrepo`)। ```text my-project/ -├── docs/ # /rpgkit.feature_spec के लिए वैकल्पिक आवश्यकता दस्तावेज़ +├── docs/ # /cmind.feature_spec के लिए वैकल्पिक आवश्यकता दस्तावेज़ ├── .github/ or .claude/ # Coding Agent कमांड परिभाषाएँ और सेटिंग्स ├── .vscode/ # लागू होने पर Copilot/VS Code MCP कॉन्फ़िगरेशन -├── .rpgkit/ # जनरेटेड रिपोर्ट और कॉन्फ़िगरेशन फ़ाइलें -└── .git/hooks/ # rpgkit init द्वारा इंस्टॉल किए गए post-commit / post-merge (प्रत्येक hook केवल एक पंक्ति: `rpgkit hook `) +├── .cmind/ # जनरेटेड रिपोर्ट और कॉन्फ़िगरेशन फ़ाइलें +└── .git/hooks/ # cmind init द्वारा इंस्टॉल किए गए post-commit / post-merge (प्रत्येक hook केवल एक पंक्ति: `cmind hook `) ``` पूर्ण लेआउट और डेटा फ़ाइल संदर्भ के लिए [docs/project-structure.md](docs/project-structure.md) देखें। -## RPG-Kit अपडेट करें +## CoderMind अपडेट करें ```bash -uv tool install rpgkit-cli \ - --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" \ +uv tool install cmind-cli \ + --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" \ --force \ --reinstall # किसी मौजूदा वर्कस्पेस को अपडेट करें cd -rpgkit update +cmind update ``` ## समर्थित प्लेटफ़ॉर्म्स @@ -234,20 +234,20 @@ rpgkit update ## दस्तावेज़ीकरण -- [स्लैश कमांड संदर्भ](docs/commands.md) — हर `/rpgkit.*` कमांड के लिए इनपुट, आउटपुट और उदाहरण। -- [CLI संदर्भ](docs/cli-reference.md) — `rpgkit init`, `rpgkit update`, `rpgkit check`, `rpgkit version` और सभी विकल्प। +- [स्लैश कमांड संदर्भ](docs/commands.md) — हर `/cmind.*` कमांड के लिए इनपुट, आउटपुट और उदाहरण। +- [CLI संदर्भ](docs/cli-reference.md) — `cmind init`, `cmind update`, `cmind check`, `cmind version` और सभी विकल्प। - [कॉन्फ़िगरेशन](docs/configuration.md) — AI सहायक सेटअप, MCP पंजीकरण, hooks, ऑटो-अनुमोदन और समस्या-निवारण। -- [परियोजना संरचना](docs/project-structure.md) — RPG-Kit द्वारा बनाई गई फ़ाइलें और निर्देशिकाएँ। +- [परियोजना संरचना](docs/project-structure.md) — CoderMind द्वारा बनाई गई फ़ाइलें और निर्देशिकाएँ। ## आगामी सुविधाएँ -- **सरल जनरेशन कमांड्स:** वर्तमान बहु-चरण जनरेशन प्रवाह को कम कमांड्स में मर्ज किया जाएगा, जैसे `/rpgkit.generate_repo`, `/rpgkit.generate_feature` और `/rpgkit.plan`। +- **सरल जनरेशन कमांड्स:** वर्तमान बहु-चरण जनरेशन प्रवाह को कम कमांड्स में मर्ज किया जाएगा, जैसे `/cmind.generate_repo`, `/cmind.generate_feature` और `/cmind.plan`। - **बहु-भाषा समर्थन:** Go, C++, Rust, JavaScript/TypeScript और अन्य के लिए समर्थन जोड़ा जाएगा। -- **अधिक प्लेटफ़ॉर्म एकीकरण:** विभिन्न सिस्टम्स पर विभिन्न AI कोडिंग एजेंट्स के लिए CLI और VS Code एक्सटेंशन वर्कफ़्लो में RPG-Kit समर्थन। +- **अधिक प्लेटफ़ॉर्म एकीकरण:** विभिन्न सिस्टम्स पर विभिन्न AI कोडिंग एजेंट्स के लिए CLI और VS Code एक्सटेंशन वर्कफ़्लो में CoderMind समर्थन। ## समस्या-निवारण -**AI सहायक CLI नहीं मिला:** `rpgkit check` चलाएँ, चयनित सहायक CLI को इंस्टॉल और प्रमाणित करें, फिर `rpgkit init` या `rpgkit update` पुनः चलाएँ। +**AI सहायक CLI नहीं मिला:** `cmind check` चलाएँ, चयनित सहायक CLI को इंस्टॉल और प्रमाणित करें, फिर `cmind init` या `cmind update` पुनः चलाएँ। ## लाइसेंस diff --git a/CoderMind/README.ja-JP.md b/CoderMind/README.ja-JP.md index 6da085b..7d9915f 100644 --- a/CoderMind/README.ja-JP.md +++ b/CoderMind/README.ja-JP.md @@ -1,4 +1,4 @@ -

RPG-Kit

+

CoderMind

English | @@ -12,9 +12,9 @@ コーディングエージェントはローカルな編集には強いものの、リポジトリレベルのタスクは安定した計画構造がないと失敗しがちです。要件はドリフトし、アーキテクチャ上の判断は失われ、複数ファイルにまたがる生成は一貫性を欠き、更新は隠れた依存関係を見落とすことがあります。 -RPG-Kit は Claude Code と GitHub Copilot に、リポジトリレベルのコーディングのための**永続的な RPG ワークスペース**を提供します。このワークスペースは、要件・機能・アーキテクチャ・ファイル・コードエンティティ・依存関係をつなぐ **Repository Planning Graph (RPG)** を中心に構成されています。 +CoderMind は Claude Code と GitHub Copilot に、リポジトリレベルのコーディングのための**永続的な RPG ワークスペース**を提供します。このワークスペースは、要件・機能・アーキテクチャ・ファイル・コードエンティティ・依存関係をつなぐ **Repository Planning Graph (RPG)** を中心に構成されています。 -RPG-Kit を使うと、エージェントはグラフ駆動のワークフローで作業できます: +CoderMind を使うと、エージェントはグラフ駆動のワークフローで作業できます: - **Build(構築)**: 要件を RPG プランに変換し、複数ファイルからなるリポジトリを生成する。 - **Understand(理解)**: 既存のリポジトリを RPG にマッピングし、検索・探索・説明する。 @@ -77,11 +77,11 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree -### RPG-Kit の実例 +### CoderMind の実例 -下の図は、本リポジトリに対して生成されたグラフ可視化の一部です。`/rpgkit.encode` を実行した後、`/.rpgkit/reports/rpg.html` を開くと完全なインタラクティブグラフを閲覧できます。現在のワークスペースの解決済みパスを見るには `rpgkit version` を実行してください。 +下の図は、本リポジトリに対して生成されたグラフ可視化の一部です。`/cmind.encode` を実行した後、`/.cmind/reports/rpg.html` を開くと完全なインタラクティブグラフを閲覧できます。現在のワークスペースの解決済みパスを見るには `cmind version` を実行してください。 -![RPG-Kit repository graph visualization](../docs/rpgkit_visualized_graph.png) +![CoderMind repository graph visualization](../docs/cmind_visualized_graph.png) ## インストール @@ -92,38 +92,38 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree - Git - インストール済みで認証済みの AI コーディングエージェント CLI: [GitHub Copilot](https://docs.github.com/en/copilot) または [Claude Code](https://docs.anthropic.com/en/docs/claude-code/setup) -### RPG-Kit のインストール +### CoderMind のインストール ```bash # 永続インストール(推奨) -uv tool install rpgkit-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" -rpgkit check +uv tool install cmind-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" +cmind check # 一度きりの使用 -uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" rpgkit init +uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" cmind init ``` -`0.1.3` 以降、wheel には pipeline scripts と slash-command templates が packaged assets として同梱されるため、`rpgkit init` はオフライン環境(air-gapped 環境や企業プロキシ環境など)でも動作します。 +`0.1.3` 以降、wheel には pipeline scripts と slash-command templates が packaged assets として同梱されるため、`cmind init` はオフライン環境(air-gapped 環境や企業プロキシ環境など)でも動作します。 ## クイックスタート: 新規リポジトリ 要件から新しいコードベースを生成したい場合は、こちらの手順を使います。 > [!WARNING] -> 生成コード量が多いプロジェクトでは、`/rpgkit.design_interfaces` と `/rpgkit.code_gen` の実行に時間がかかることがあります。例として、100 個の feature でおおよそ 30 分かかります。 +> 生成コード量が多いプロジェクトでは、`/cmind.design_interfaces` と `/cmind.code_gen` の実行に時間がかかることがあります。例として、100 個の feature でおおよそ 30 分かかります。 1. 新しいプロジェクトを初期化します: ```bash - rpgkit init my-project + cmind init my-project cd my-project ``` よく使うバリエーション: ```bash - rpgkit init my-project --ai claude --script sh - rpgkit init my-project --ai copilot + cmind init my-project --ai claude --script sh + cmind init my-project --ai copilot ``` 2. **[任意]** 要件ドキュメントを `my-project/docs/` に配置します。 @@ -133,45 +133,45 @@ uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-K 4. フォワードパイプラインを実行します: ```text - /rpgkit.feature_spec - /rpgkit.feature_build - /rpgkit.feature_refactor - [Optional] /rpgkit.feature_edit - /rpgkit.build_skeleton - /rpgkit.build_data_flow - /rpgkit.design_base_classes - /rpgkit.design_interfaces - /rpgkit.plan_tasks - /rpgkit.code_gen - [Optional] /rpgkit.rpg_edit + /cmind.feature_spec + /cmind.feature_build + /cmind.feature_refactor + [Optional] /cmind.feature_edit + /cmind.build_skeleton + /cmind.build_data_flow + /cmind.design_base_classes + /cmind.design_interfaces + /cmind.plan_tasks + /cmind.code_gen + [Optional] /cmind.rpg_edit ``` > [!IMPORTANT] > **コーディングエージェントごとに呼び出し方が異なります**: > -> - **Claude Code**:チャットにそのまま `/rpgkit.feature_spec ...` と入力します。slash command が認識され、対応する workflow がトリガーされます。 -> - **GitHub Copilot CLI**:slash command はサポートされません(カスタム agent はサポート)。まず `/agent rpgkit.feature_spec` で目的の agent に切り替え、その後 `start` と入力して内蔵の workflow を実行します。 +> - **Claude Code**:チャットにそのまま `/cmind.feature_spec ...` と入力します。slash command が認識され、対応する workflow がトリガーされます。 +> - **GitHub Copilot CLI**:slash command はサポートされません(カスタム agent はサポート)。まず `/agent cmind.feature_spec` で目的の agent に切り替え、その後 `start` と入力して内蔵の workflow を実行します。 -RPG-Kit は `~/.rpgkit/workspaces//data/rpg.json` を段階的に作成し、それを使って要件・計画成果物・生成コード・依存情報を整合した状態に保ちます。ワークスペースのソースファイルは汚染されません。 +CoderMind は `~/.cmind/workspaces//data/rpg.json` を段階的に作成し、それを使って要件・計画成果物・生成コード・依存情報を整合した状態に保ちます。ワークスペースのソースファイルは汚染されません。 ## クイックスタート: 既存リポジトリ すでにリポジトリがあり、AI エージェントに RPG コンテキストで理解または編集させたい場合は、こちらの手順を使います。 > [!WARNING] -> 大きめのプロジェクトでは、`rpgkit init . --encode` と `/rpgkit.encode` の実行に時間がかかることがあります。例として、200 ファイルでおおよそ 100 分かかります。 +> 大きめのプロジェクトでは、`cmind init . --encode` と `/cmind.encode` の実行に時間がかかることがあります。例として、200 ファイルでおおよそ 100 分かかります。 -1. リポジトリのルートで RPG-Kit を初期化し、初期グラフを構築します: +1. リポジトリのルートで CoderMind を初期化し、初期グラフを構築します: ```bash cd existing-repo/ - rpgkit init . --encode # --encode は現在のコードから RPG を生成します + cmind init . --encode # --encode は現在のコードから RPG を生成します ``` 空でないディレクトリでの確認プロンプトをスキップしたい場合: ```bash - rpgkit init . --force --encode + cmind init . --force --encode ``` 2. リポジトリで AI コーディングエージェントを起動します。 @@ -179,39 +179,39 @@ RPG-Kit は `~/.rpgkit/workspaces//data/rpg.json` を段階的に 3. **[任意]** 生成された RPG を MCP ツールおよびスラッシュコマンド経由で利用します。以下のコマンドは手動で実行する場合にのみ必要です: ```text - /rpgkit.encode # 必要に応じて完全な RPG を再構築 - /rpgkit.update_rpg # 手動の増分更新(フォールバック) - /rpgkit.rpg_edit # グラフ認識型のコード編集 + /cmind.encode # 必要に応じて完全な RPG を再構築 + /cmind.update_rpg # 手動の増分更新(フォールバック) + /cmind.rpg_edit # グラフ認識型のコード編集 ``` -4. 各 commit の後、RPG-Kit がインストールした git hook が `rpgkit hook ` ディスパッチャを自動的に呼び出し、RPG を更新してコード変更と整合した状態に保ちます。hook が失敗したりスキップされたりした場合は、`/rpgkit.update_rpg` を手動で実行してください。 +4. 各 commit の後、CoderMind がインストールした git hook が `cmind hook ` ディスパッチャを自動的に呼び出し、RPG を更新してコード変更と整合した状態に保ちます。hook が失敗したりスキップされたりした場合は、`/cmind.update_rpg` を手動で実行してください。 -## `rpgkit init` の後に起きること +## `cmind init` の後に起きること -`rpgkit init` はソースファイルを変更しません。また、**ワークスペースにランタイム状態を書き込みません**。ワークスペースには command 定義、MCP 設定、および hooks のみを追加します。RPG-Kit のランタイムデータ(成果物、ログ)は home-side ディレクトリ `~/.rpgkit/workspaces//` 下に配置されます。`` はワークスペースの絶対パスから導出される可読な slug です(例: `home-hys-projects-myrepo`)。 +`cmind init` はソースファイルを変更しません。また、**ワークスペースにランタイム状態を書き込みません**。ワークスペースには command 定義、MCP 設定、および hooks のみを追加します。CoderMind のランタイムデータ(成果物、ログ)は home-side ディレクトリ `~/.cmind/workspaces//` 下に配置されます。`` はワークスペースの絶対パスから導出される可読な slug です(例: `home-hys-projects-myrepo`)。 ```text my-project/ -├── docs/ # /rpgkit.feature_spec 用の任意の要件ドキュメント +├── docs/ # /cmind.feature_spec 用の任意の要件ドキュメント ├── .github/ or .claude/ # Coding Agent のコマンド定義と設定 ├── .vscode/ # 該当する場合の Copilot/VS Code MCP 設定 -├── .rpgkit/ # 生成されたレポートと設定ファイル -└── .git/hooks/ # rpgkit init が設置する post-commit / post-merge(各 hook は 1 行のみ: `rpgkit hook `) +├── .cmind/ # 生成されたレポートと設定ファイル +└── .git/hooks/ # cmind init が設置する post-commit / post-merge(各 hook は 1 行のみ: `cmind hook `) ``` 完全なレイアウトとデータファイルのリファレンスは [docs/project-structure.md](docs/project-structure.md) を参照してください。 -## RPG-Kit の更新 +## CoderMind の更新 ```bash -uv tool install rpgkit-cli \ - --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" \ +uv tool install cmind-cli \ + --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" \ --force \ --reinstall # 既存のワークスペースを更新 cd -rpgkit update +cmind update ``` ## 対応プラットフォーム @@ -234,20 +234,20 @@ rpgkit update ## ドキュメント -- [スラッシュコマンドリファレンス](docs/commands.md) — すべての `/rpgkit.*` コマンドの入力・出力・例。 -- [CLI リファレンス](docs/cli-reference.md) — `rpgkit init`、`rpgkit update`、`rpgkit check`、`rpgkit version` とすべてのオプション。 +- [スラッシュコマンドリファレンス](docs/commands.md) — すべての `/cmind.*` コマンドの入力・出力・例。 +- [CLI リファレンス](docs/cli-reference.md) — `cmind init`、`cmind update`、`cmind check`、`cmind version` とすべてのオプション。 - [設定](docs/configuration.md) — AI アシスタントのセットアップ、MCP 登録、フック、自動承認、およびトラブルシューティング。 -- [プロジェクト構造](docs/project-structure.md) — RPG-Kit が作成するファイルとディレクトリ。 +- [プロジェクト構造](docs/project-structure.md) — CoderMind が作成するファイルとディレクトリ。 ## 今後の機能 -- **よりシンプルな生成コマンド:** 現在の多段階の生成フローを、`/rpgkit.generate_repo`、`/rpgkit.generate_feature`、`/rpgkit.plan` などのより少ないコマンドにまとめます。 +- **よりシンプルな生成コマンド:** 現在の多段階の生成フローを、`/cmind.generate_repo`、`/cmind.generate_feature`、`/cmind.plan` などのより少ないコマンドにまとめます。 - **多言語サポート:** Go、C++、Rust、JavaScript/TypeScript などのサポートを追加します。 -- **より多くのプラットフォーム連携:** さまざまなシステム上の異なる AI コーディングエージェントについて、CLI と VS Code 拡張ワークフローを横断して RPG-Kit をサポートします。 +- **より多くのプラットフォーム連携:** さまざまなシステム上の異なる AI コーディングエージェントについて、CLI と VS Code 拡張ワークフローを横断して CoderMind をサポートします。 ## トラブルシューティング -**AI アシスタント CLI が見つからない:** `rpgkit check` を実行し、選択したアシスタント CLI をインストールおよび認証し、`rpgkit init` または `rpgkit update` を再実行してください。 +**AI アシスタント CLI が見つからない:** `cmind check` を実行し、選択したアシスタント CLI をインストールおよび認証し、`cmind init` または `cmind update` を再実行してください。 ## ライセンス diff --git a/CoderMind/README.ko-KR.md b/CoderMind/README.ko-KR.md index c770511..66be341 100644 --- a/CoderMind/README.ko-KR.md +++ b/CoderMind/README.ko-KR.md @@ -1,4 +1,4 @@ -

RPG-Kit

+

CoderMind

English | @@ -12,9 +12,9 @@ 코딩 에이전트는 로컬 편집에는 강하지만, 안정적인 계획 구조가 없으면 저장소 수준의 작업은 실패하기 쉽습니다. 요구사항이 흐트러지고, 아키텍처 결정이 사라지고, 여러 파일에 걸친 생성이 일관성을 잃으며, 업데이트가 숨겨진 의존성을 놓칠 수 있습니다. -RPG-Kit은 Claude Code와 GitHub Copilot에 저장소 수준의 코딩을 위한 **영속적인 RPG 워크스페이스**를 제공합니다. 이 워크스페이스는 요구사항, 기능, 아키텍처, 파일, 코드 엔티티, 의존성을 연결하는 **Repository Planning Graph (RPG)** 를 중심으로 구성되어 있습니다. +CoderMind은 Claude Code와 GitHub Copilot에 저장소 수준의 코딩을 위한 **영속적인 RPG 워크스페이스**를 제공합니다. 이 워크스페이스는 요구사항, 기능, 아키텍처, 파일, 코드 엔티티, 의존성을 연결하는 **Repository Planning Graph (RPG)** 를 중심으로 구성되어 있습니다. -RPG-Kit을 사용하면 에이전트는 그래프 기반 워크플로로 작업할 수 있습니다: +CoderMind을 사용하면 에이전트는 그래프 기반 워크플로로 작업할 수 있습니다: - **Build (구축)**: 요구사항을 RPG 계획으로 바꾼 다음 여러 파일로 구성된 저장소를 생성합니다. - **Understand (이해)**: 기존 저장소를 RPG로 매핑한 다음 검색, 탐색, 설명합니다. @@ -77,11 +77,11 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree -### RPG-Kit 실제 사용 예 +### CoderMind 실제 사용 예 -아래 이미지는 이 저장소에서 생성된 그래프 시각화의 일부입니다. `/rpgkit.encode` 를 실행한 후 `/.rpgkit/reports/rpg.html` 을 열면 전체 인터랙티브 그래프를 탐색할 수 있습니다. 현재 워크스페이스의 해결된 경로를 보려면 `rpgkit version` 을 실행하세요. +아래 이미지는 이 저장소에서 생성된 그래프 시각화의 일부입니다. `/cmind.encode` 를 실행한 후 `/.cmind/reports/rpg.html` 을 열면 전체 인터랙티브 그래프를 탐색할 수 있습니다. 현재 워크스페이스의 해결된 경로를 보려면 `cmind version` 을 실행하세요. -![RPG-Kit repository graph visualization](../docs/rpgkit_visualized_graph.png) +![CoderMind repository graph visualization](../docs/cmind_visualized_graph.png) ## 설치 @@ -92,38 +92,38 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree - Git - 설치 및 인증이 완료된 AI 코딩 에이전트 CLI: [GitHub Copilot](https://docs.github.com/en/copilot) 또는 [Claude Code](https://docs.anthropic.com/en/docs/claude-code/setup) -### RPG-Kit 설치 +### CoderMind 설치 ```bash # 영속 설치 (권장) -uv tool install rpgkit-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" -rpgkit check +uv tool install cmind-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" +cmind check # 일회성 사용 -uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" rpgkit init +uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" cmind init ``` -`0.1.3` 부터 wheel은 pipeline scripts와 slash-command templates를 packaged assets로 함께 제공하므로, `rpgkit init` 은 오프라인 환경(air-gapped 환경, 회사 프록시 환경 등)에서도 동작합니다. +`0.1.3` 부터 wheel은 pipeline scripts와 slash-command templates를 packaged assets로 함께 제공하므로, `cmind init` 은 오프라인 환경(air-gapped 환경, 회사 프록시 환경 등)에서도 동작합니다. ## Quick Start: 새 저장소 요구사항을 새 코드베이스로 만들고 싶을 때 이 경로를 사용하세요. > [!WARNING] -> 생성 코드 양이 많은 프로젝트의 경우, `/rpgkit.design_interfaces` 와 `/rpgkit.code_gen` 의 실행 시간이 길어질 수 있습니다. 예시: 100개의 feature는 약 30분이 걸립니다. +> 생성 코드 양이 많은 프로젝트의 경우, `/cmind.design_interfaces` 와 `/cmind.code_gen` 의 실행 시간이 길어질 수 있습니다. 예시: 100개의 feature는 약 30분이 걸립니다. 1. 새 프로젝트를 초기화합니다: ```bash - rpgkit init my-project + cmind init my-project cd my-project ``` 자주 사용하는 변형: ```bash - rpgkit init my-project --ai claude --script sh - rpgkit init my-project --ai copilot + cmind init my-project --ai claude --script sh + cmind init my-project --ai copilot ``` 2. **[선택]** 요구사항 문서를 `my-project/docs/` 에 둡니다. @@ -133,45 +133,45 @@ uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-K 4. 포워드 파이프라인을 실행합니다: ```text - /rpgkit.feature_spec - /rpgkit.feature_build - /rpgkit.feature_refactor - [Optional] /rpgkit.feature_edit - /rpgkit.build_skeleton - /rpgkit.build_data_flow - /rpgkit.design_base_classes - /rpgkit.design_interfaces - /rpgkit.plan_tasks - /rpgkit.code_gen - [Optional] /rpgkit.rpg_edit + /cmind.feature_spec + /cmind.feature_build + /cmind.feature_refactor + [Optional] /cmind.feature_edit + /cmind.build_skeleton + /cmind.build_data_flow + /cmind.design_base_classes + /cmind.design_interfaces + /cmind.plan_tasks + /cmind.code_gen + [Optional] /cmind.rpg_edit ``` > [!IMPORTANT] > **Coding Agent마다 호출 방식이 조금씩 다릅니다**: > -> - **Claude Code**: 채팅에 직접 `/rpgkit.feature_spec ...` 을 입력하면 slash command가 인식되어 해당 workflow가 트리거됩니다. -> - **GitHub Copilot CLI**: slash command는 지원하지 않으나(커스텀 agent는 지원), 먼저 `/agent rpgkit.feature_spec` 으로 대상 agent로 전환한 다음 `start` 를 입력해 내장된 workflow를 실행합니다. +> - **Claude Code**: 채팅에 직접 `/cmind.feature_spec ...` 을 입력하면 slash command가 인식되어 해당 workflow가 트리거됩니다. +> - **GitHub Copilot CLI**: slash command는 지원하지 않으나(커스텀 agent는 지원), 먼저 `/agent cmind.feature_spec` 으로 대상 agent로 전환한 다음 `start` 를 입력해 내장된 workflow를 실행합니다. -RPG-Kit은 `~/.rpgkit/workspaces//data/rpg.json` 을 점진적으로 생성하고, 이를 사용해 요구사항, 계획 산출물, 생성된 코드, 의존성 정보를 정합 상태로 유지합니다. 워크스페이스의 소스 파일은 오염되지 않습니다. +CoderMind은 `~/.cmind/workspaces//data/rpg.json` 을 점진적으로 생성하고, 이를 사용해 요구사항, 계획 산출물, 생성된 코드, 의존성 정보를 정합 상태로 유지합니다. 워크스페이스의 소스 파일은 오염되지 않습니다. ## Quick Start: 기존 저장소 이미 저장소가 있고, AI 에이전트가 RPG 컨텍스트로 이해하거나 편집하기를 원할 때 이 경로를 사용하세요. > [!WARNING] -> 큰 프로젝트의 경우, `rpgkit init . --encode` 와 `/rpgkit.encode` 의 실행 시간이 길어질 수 있습니다. 예시: 200개 소스 파일은 약 100분이 걸립니다. +> 큰 프로젝트의 경우, `cmind init . --encode` 와 `/cmind.encode` 의 실행 시간이 길어질 수 있습니다. 예시: 200개 소스 파일은 약 100분이 걸립니다. -1. 저장소 루트에서 RPG-Kit을 초기화하고 초기 그래프를 생성합니다: +1. 저장소 루트에서 CoderMind을 초기화하고 초기 그래프를 생성합니다: ```bash cd existing-repo/ - rpgkit init . --encode # --encode 는 현재 코드로부터 RPG를 생성합니다 + cmind init . --encode # --encode 는 현재 코드로부터 RPG를 생성합니다 ``` 비어 있지 않은 디렉터리에 대한 확인 프롬프트를 건너뛰려면: ```bash - rpgkit init . --force --encode + cmind init . --force --encode ``` 2. 저장소에서 AI 코딩 에이전트를 실행합니다. @@ -179,39 +179,39 @@ RPG-Kit은 `~/.rpgkit/workspaces//data/rpg.json` 을 점진적으 3. **[선택]** MCP 도구와 슬래시 커맨드를 통해 생성된 RPG를 사용합니다. 아래 명령은 수동으로 실행할 때만 필요합니다: ```text - /rpgkit.encode # 필요할 때 전체 RPG 재구축 - /rpgkit.update_rpg # 수동 증분 업데이트 (폴백) - /rpgkit.rpg_edit # 그래프 인식 코드 편집 + /cmind.encode # 필요할 때 전체 RPG 재구축 + /cmind.update_rpg # 수동 증분 업데이트 (폴백) + /cmind.rpg_edit # 그래프 인식 코드 편집 ``` -4. 각 commit 후, RPG-Kit이 설치한 git hook이 `rpgkit hook ` 디스패처를 자동으로 호출해 RPG를 업데이트하고 코드 변경과 정합된 상태로 유지합니다. hook이 실패하거나 건너뛰어진 경우 `/rpgkit.update_rpg` 를 수동으로 실행하세요. +4. 각 commit 후, CoderMind이 설치한 git hook이 `cmind hook ` 디스패처를 자동으로 호출해 RPG를 업데이트하고 코드 변경과 정합된 상태로 유지합니다. hook이 실패하거나 건너뛰어진 경우 `/cmind.update_rpg` 를 수동으로 실행하세요. -## `rpgkit init` 이후 일어나는 일 +## `cmind init` 이후 일어나는 일 -`rpgkit init` 은 소스 파일을 수정하지 않습니다. 또한 **워크스페이스에 런타임 상태를 기록하지도 않습니다**. 워크스페이스에는 command 정의, MCP 구성, hooks만 추가합니다. RPG-Kit의 런타임 데이터(산출물, 로그)는 home-side 디렉터리 `~/.rpgkit/workspaces//` 아래에 배치되며, `` 는 워크스페이스의 절대 경로에서 파생된 가독성 있는 slug입니다 (예: `home-hys-projects-myrepo`). +`cmind init` 은 소스 파일을 수정하지 않습니다. 또한 **워크스페이스에 런타임 상태를 기록하지도 않습니다**. 워크스페이스에는 command 정의, MCP 구성, hooks만 추가합니다. CoderMind의 런타임 데이터(산출물, 로그)는 home-side 디렉터리 `~/.cmind/workspaces//` 아래에 배치되며, `` 는 워크스페이스의 절대 경로에서 파생된 가독성 있는 slug입니다 (예: `home-hys-projects-myrepo`). ```text my-project/ -├── docs/ # /rpgkit.feature_spec 용 선택적 요구사항 문서 +├── docs/ # /cmind.feature_spec 용 선택적 요구사항 문서 ├── .github/ or .claude/ # Coding Agent 커맨드 정의 및 설정 ├── .vscode/ # 해당하는 경우 Copilot/VS Code MCP 구성 -├── .rpgkit/ # 생성된 리포트와 설정 파일 -└── .git/hooks/ # rpgkit init 이 설치하는 post-commit / post-merge (각 hook은 단 한 줄: `rpgkit hook `) +├── .cmind/ # 생성된 리포트와 설정 파일 +└── .git/hooks/ # cmind init 이 설치하는 post-commit / post-merge (각 hook은 단 한 줄: `cmind hook `) ``` 전체 레이아웃과 데이터 파일 참조는 [docs/project-structure.md](docs/project-structure.md) 를 참조하세요. -## RPG-Kit 업데이트 +## CoderMind 업데이트 ```bash -uv tool install rpgkit-cli \ - --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" \ +uv tool install cmind-cli \ + --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" \ --force \ --reinstall # 기존 워크스페이스 업데이트 cd -rpgkit update +cmind update ``` ## 지원 플랫폼 @@ -234,20 +234,20 @@ rpgkit update ## 문서 -- [슬래시 커맨드 레퍼런스](docs/commands.md) — 모든 `/rpgkit.*` 커맨드의 입력, 출력, 예시. -- [CLI 레퍼런스](docs/cli-reference.md) — `rpgkit init`, `rpgkit update`, `rpgkit check`, `rpgkit version` 및 모든 옵션. +- [슬래시 커맨드 레퍼런스](docs/commands.md) — 모든 `/cmind.*` 커맨드의 입력, 출력, 예시. +- [CLI 레퍼런스](docs/cli-reference.md) — `cmind init`, `cmind update`, `cmind check`, `cmind version` 및 모든 옵션. - [구성](docs/configuration.md) — AI 어시스턴트 설정, MCP 등록, 훅, 자동 승인 및 트러블슈팅. -- [프로젝트 구조](docs/project-structure.md) — RPG-Kit이 생성하는 파일과 디렉터리. +- [프로젝트 구조](docs/project-structure.md) — CoderMind이 생성하는 파일과 디렉터리. ## 예정된 기능 -- **더 간단한 생성 커맨드:** 현재의 다단계 생성 흐름을 `/rpgkit.generate_repo`, `/rpgkit.generate_feature`, `/rpgkit.plan` 등 더 적은 커맨드로 통합합니다. +- **더 간단한 생성 커맨드:** 현재의 다단계 생성 흐름을 `/cmind.generate_repo`, `/cmind.generate_feature`, `/cmind.plan` 등 더 적은 커맨드로 통합합니다. - **다국어 지원:** Go, C++, Rust, JavaScript/TypeScript 등을 추가로 지원합니다. -- **더 많은 플랫폼 통합:** 다양한 시스템에서 서로 다른 AI 코딩 에이전트의 CLI 및 VS Code 확장 워크플로에 걸쳐 RPG-Kit을 지원합니다. +- **더 많은 플랫폼 통합:** 다양한 시스템에서 서로 다른 AI 코딩 에이전트의 CLI 및 VS Code 확장 워크플로에 걸쳐 CoderMind을 지원합니다. ## 트러블슈팅 -**AI 어시스턴트 CLI를 찾을 수 없음:** `rpgkit check` 를 실행하고, 선택한 어시스턴트 CLI를 설치 및 인증한 다음 `rpgkit init` 또는 `rpgkit update` 를 다시 실행하세요. +**AI 어시스턴트 CLI를 찾을 수 없음:** `cmind check` 를 실행하고, 선택한 어시스턴트 CLI를 설치 및 인증한 다음 `cmind init` 또는 `cmind update` 를 다시 실행하세요. ## 라이선스 diff --git a/CoderMind/README.md b/CoderMind/README.md index 3f93e6e..917ad86 100644 --- a/CoderMind/README.md +++ b/CoderMind/README.md @@ -1,4 +1,4 @@ -

CoderMind (formerly RPG-Kit)

+

CoderMind

English | @@ -9,7 +9,7 @@

> [!NOTE] -> **CoderMind** is the new name for **RPG-Kit**. The product has been renamed; the install command (`rpgkit`) and package (`rpgkit-cli`) will be renamed in a subsequent release. +> CoderMind is at an early stage (v0.1.x). Interfaces may still change. ## Make coding agents plan before they edit @@ -82,9 +82,9 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree ### CoderMind in action -Below is part of the graph visualization generated for this repository. After running `/rpgkit.encode`, you can open `/.rpgkit/reports/rpg.html` to browse the full interactive graph. Run `rpgkit version` to see the resolved paths for the current workspace. +Below is part of the graph visualization generated for this repository. After running `/cmind.encode`, you can open `/.cmind/reports/rpg.html` to browse the full interactive graph. Run `cmind version` to see the resolved paths for the current workspace. -![CoderMind repository graph visualization](../docs/rpgkit_visualized_graph.png) +![CoderMind repository graph visualization](../docs/cmind_visualized_graph.png) ## Installation @@ -99,34 +99,34 @@ Below is part of the graph visualization generated for this repository. After ru ```bash # For persistent installation (Recommended) -uv tool install rpgkit-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" -rpgkit check +uv tool install cmind-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" +cmind check # For one-time usage -uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" rpgkit init +uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" cmind init ``` -Since `0.1.3`, the wheel ships the pipeline scripts and slash-command templates as packaged assets, so `rpgkit init` works offline (for example in air-gapped or corporate proxy environments). +Since `0.1.3`, the wheel ships the pipeline scripts and slash-command templates as packaged assets, so `cmind init` works offline (for example in air-gapped or corporate proxy environments). ## Quick Start: New Repository Use this path when you want CoderMind to turn requirements into a new codebase. > [!WARNING] -> For projects with a large amount of generated code, `/rpgkit.design_interfaces` and `/rpgkit.code_gen` can take a long time to run. As a typical example: 100 features take about 30 minutes. +> For projects with a large amount of generated code, `/cmind.design_interfaces` and `/cmind.code_gen` can take a long time to run. As a typical example: 100 features take about 30 minutes. 1. Initialize a new project: ```bash - rpgkit init my-project + cmind init my-project cd my-project ``` Common variants: ```bash - rpgkit init my-project --ai claude --script sh - rpgkit init my-project --ai copilot + cmind init my-project --ai claude --script sh + cmind init my-project --ai copilot ``` 2. **[Optional]** place your requirement documents in `my-project/docs/`. @@ -136,45 +136,45 @@ Use this path when you want CoderMind to turn requirements into a new codebase. 4. Run the forward pipeline: ```text - /rpgkit.feature_spec - /rpgkit.feature_build - /rpgkit.feature_refactor - [Optional] /rpgkit.feature_edit - /rpgkit.build_skeleton - /rpgkit.build_data_flow - /rpgkit.design_base_classes - /rpgkit.design_interfaces - /rpgkit.plan_tasks - /rpgkit.code_gen - [Optional] /rpgkit.rpg_edit + /cmind.feature_spec + /cmind.feature_build + /cmind.feature_refactor + [Optional] /cmind.feature_edit + /cmind.build_skeleton + /cmind.build_data_flow + /cmind.design_base_classes + /cmind.design_interfaces + /cmind.plan_tasks + /cmind.code_gen + [Optional] /cmind.rpg_edit ``` > [!IMPORTANT] > **Coding Agents are invoked slightly differently**: > -> - **Claude Code**: type `/rpgkit.feature_spec ...` directly in the chat — slash commands are recognised and dispatch the matching workflow. -> - **GitHub Copilot CLI**: slash commands are not supported (custom agents are), so first run `/agent rpgkit.feature_spec` to switch to the target agent, then type `start` to run its built-in workflow. +> - **Claude Code**: type `/cmind.feature_spec ...` directly in the chat — slash commands are recognised and dispatch the matching workflow. +> - **GitHub Copilot CLI**: slash commands are not supported (custom agents are), so first run `/agent cmind.feature_spec` to switch to the target agent, then type `start` to run its built-in workflow. -CoderMind progressively builds `rpg.json` in the home-side runtime directory (`~/.rpgkit/workspaces//data/rpg.json`) and uses it to keep requirements, planning artifacts, generated code, and dependency information aligned. Your workspace source files are not polluted. +CoderMind progressively builds `rpg.json` in the home-side runtime directory (`~/.cmind/workspaces//data/rpg.json`) and uses it to keep requirements, planning artifacts, generated code, and dependency information aligned. Your workspace source files are not polluted. ## Quick Start: Existing Repository Use this path when you already have a repository and want an AI agent to understand or edit it with RPG context. > [!WARNING] -> For larger projects, `rpgkit init . --encode` and `/rpgkit.encode` can take a long time to run. As a typical example: 200 source files take about 100 minutes. +> For larger projects, `cmind init . --encode` and `/cmind.encode` can take a long time to run. As a typical example: 200 source files take about 100 minutes. 1. Initialize CoderMind in the repository root and build the initial graph: ```bash cd existing-repo/ - rpgkit init . --encode # --encode builds the RPG from the current code + cmind init . --encode # --encode builds the RPG from the current code ``` If you want to skip the confirmation prompt for a non-empty directory: ```bash - rpgkit init . --force --encode + cmind init . --force --encode ``` 2. Launch your AI coding agent in the repository. @@ -182,24 +182,24 @@ Use this path when you already have a repository and want an AI agent to underst 3. **[Optional]** Use the generated RPG through MCP tools and slash commands. The following commands are only needed when run manually: ```text - /rpgkit.encode # rebuild the full RPG when needed - /rpgkit.update_rpg # manual incremental update fallback - /rpgkit.rpg_edit # graph-aware code edit + /cmind.encode # rebuild the full RPG when needed + /cmind.update_rpg # manual incremental update fallback + /cmind.rpg_edit # graph-aware code edit ``` -4. After each commit, the git hook installed by CoderMind automatically calls the `rpgkit hook ` dispatcher to update the RPG and keep it aligned with code changes. If the hook fails or is skipped, run `/rpgkit.update_rpg` manually. +4. After each commit, the git hook installed by CoderMind automatically calls the `cmind hook ` dispatcher to update the RPG and keep it aligned with code changes. If the hook fails or is skipped, run `/cmind.update_rpg` manually. -## What happens after `rpgkit init` +## What happens after `cmind init` -`rpgkit init` does not modify your source files, **and it does not write runtime state into your workspace**. It only adds command definitions, MCP configuration, and hooks to your workspace. CoderMind runtime data (artifacts and logs) lives under the home-side directory `~/.rpgkit/workspaces//`, where `` is a slug derived from the workspace's absolute path (e.g. `home-hys-projects-myrepo`). +`cmind init` does not modify your source files, **and it does not write runtime state into your workspace**. It only adds command definitions, MCP configuration, and hooks to your workspace. CoderMind runtime data (artifacts and logs) lives under the home-side directory `~/.cmind/workspaces//`, where `` is a slug derived from the workspace's absolute path (e.g. `home-hys-projects-myrepo`). ```text my-project/ -├── docs/ # Optional requirement docs for /rpgkit.feature_spec +├── docs/ # Optional requirement docs for /cmind.feature_spec ├── .github/ or .claude/ # Coding Agent command definitions and settings ├── .vscode/ # Copilot/VS Code MCP configuration when applicable -├── .rpgkit/ # Generated reports and configuration files -└── .git/hooks/ # post-commit / post-merge installed by rpgkit init (each hook is one line: `rpgkit hook `) +├── .cmind/ # Generated reports and configuration files +└── .git/hooks/ # post-commit / post-merge installed by cmind init (each hook is one line: `cmind hook `) ``` See [docs/project-structure.md](docs/project-structure.md) for the full layout and data file reference. @@ -207,14 +207,14 @@ See [docs/project-structure.md](docs/project-structure.md) for the full layout a ## Updating CoderMind ```bash -uv tool install rpgkit-cli \ +uv tool install cmind-cli \ --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" \ --force \ --reinstall # Update an existing workspace cd -rpgkit update +cmind update ``` ## Supported Platforms @@ -237,20 +237,20 @@ rpgkit update ## Documentation -- [Slash command reference](docs/commands.md) — every `/rpgkit.*` command, inputs, outputs, and examples. -- [CLI reference](docs/cli-reference.md) — `rpgkit init`, `rpgkit update`, `rpgkit check`, `rpgkit version`, and all options. +- [Slash command reference](docs/commands.md) — every `/cmind.*` command, inputs, outputs, and examples. +- [CLI reference](docs/cli-reference.md) — `cmind init`, `cmind update`, `cmind check`, `cmind version`, and all options. - [Configuration](docs/configuration.md) — AI assistant setup, MCP registration, hooks, auto-approval, and troubleshooting. - [Project structure](docs/project-structure.md) — files and directories created by CoderMind. ## Upcoming Features -- **Simpler generation commands:** merge the current multi-step generation flow into fewer commands, such as `/rpgkit.generate_repo`, `/rpgkit.generate_feature`, and `/rpgkit.plan`. +- **Simpler generation commands:** merge the current multi-step generation flow into fewer commands, such as `/cmind.generate_repo`, `/cmind.generate_feature`, and `/cmind.plan`. - **Multi-language support:** add support for Go, C++, Rust, JavaScript/TypeScript, and more. - **More platform integrations:** support CoderMind across CLI and VS Code extension workflows for different AI coding agents on different systems. ## Troubleshooting -**AI assistant CLI not found:** run `rpgkit check`, install and authenticate the selected assistant CLI, then rerun `rpgkit init` or `rpgkit update`. +**AI assistant CLI not found:** run `cmind check`, install and authenticate the selected assistant CLI, then rerun `cmind init` or `cmind update`. ## License diff --git a/CoderMind/README.zh-CN.md b/CoderMind/README.zh-CN.md index 90ffcdb..0b436dc 100644 --- a/CoderMind/README.zh-CN.md +++ b/CoderMind/README.zh-CN.md @@ -1,4 +1,4 @@ -

RPG-Kit

+

CoderMind

English | @@ -12,9 +12,9 @@ 编码智能体擅长局部编辑,但仓库级任务如果缺少稳定的规划结构往往会失败:需求漂移、架构决策丢失、多文件生成前后不一致、更新可能错过隐藏依赖。 -RPG-Kit 为 Claude Code 和 GitHub Copilot 提供一个面向仓库级编码的**持久化 RPG 工作区**。这个工作区围绕一个 **Repository Planning Graph (RPG)** 构建,把需求、功能、架构、文件、代码实体和依赖关系连接在一起。 +CoderMind 为 Claude Code 和 GitHub Copilot 提供一个面向仓库级编码的**持久化 RPG 工作区**。这个工作区围绕一个 **Repository Planning Graph (RPG)** 构建,把需求、功能、架构、文件、代码实体和依赖关系连接在一起。 -借助 RPG-Kit,智能体可以通过图驱动的工作流来工作: +借助 CoderMind,智能体可以通过图驱动的工作流来工作: - **构建(Build)**:把需求转换为 RPG 规划,然后生成一个多文件仓库。 - **理解(Understand)**:把已有仓库映射为 RPG,然后搜索、浏览和解释它。 @@ -77,11 +77,11 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree -### RPG-Kit 实际效果 +### CoderMind 实际效果 -下图是为本仓库生成的图可视化的一部分。运行 `/rpgkit.encode` 后,可以打开 `/.rpgkit/reports/rpg.html` 浏览完整的交互式图。运行 `rpgkit version` 可以看到当前工作区的具体路径。 +下图是为本仓库生成的图可视化的一部分。运行 `/cmind.encode` 后,可以打开 `/.cmind/reports/rpg.html` 浏览完整的交互式图。运行 `cmind version` 可以看到当前工作区的具体路径。 -![RPG-Kit repository graph visualization](../docs/rpgkit_visualized_graph.png) +![CoderMind repository graph visualization](../docs/cmind_visualized_graph.png) ## 安装 @@ -92,38 +92,38 @@ MCP Server: search_rpg / explore_rpg / get_node_detail / list_rpg_tree - Git - 一个已安装并完成身份验证的 Coding Agent CLI:[GitHub Copilot](https://docs.github.com/en/copilot) 或 [Claude Code](https://docs.anthropic.com/en/docs/claude-code/setup) -### 安装 RPG-Kit +### 安装 CoderMind ```bash # 持久化安装(推荐) -uv tool install rpgkit-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" -rpgkit check +uv tool install cmind-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" +cmind check # 一次性使用 -uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" rpgkit init +uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" cmind init ``` -从 `0.1.3` 开始,wheel 会把 pipeline scripts 和 slash-command templates 作为打包资源一起发布,因此 `rpgkit init` 可以离线工作(例如 air-gapped 环境、公司代理环境等)。 +从 `0.1.3` 开始,wheel 会把 pipeline scripts 和 slash-command templates 作为打包资源一起发布,因此 `cmind init` 可以离线工作(例如 air-gapped 环境、公司代理环境等)。 ## 快速开始:新仓库 -当你希望 RPG-Kit 把需求转换为新代码库时,使用此路径。 +当你希望 CoderMind 把需求转换为新代码库时,使用此路径。 > [!WARNING] -> 对于生成代码量较大的项目,`/rpgkit.design_interfaces` 和 `/rpgkit.code_gen` 可能运行较长时间。典型例子:100 个 feature 大约需要 30 分钟。 +> 对于生成代码量较大的项目,`/cmind.design_interfaces` 和 `/cmind.code_gen` 可能运行较长时间。典型例子:100 个 feature 大约需要 30 分钟。 1. 初始化一个新项目: ```bash - rpgkit init my-project + cmind init my-project cd my-project ``` 常见变体: ```bash - rpgkit init my-project --ai claude --script sh - rpgkit init my-project --ai copilot + cmind init my-project --ai claude --script sh + cmind init my-project --ai copilot ``` 2. **[可选]** 把你的需求文档放在 `my-project/docs/`。 @@ -133,45 +133,45 @@ uvx --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-K 4. 运行正向流水线: ```text - /rpgkit.feature_spec - /rpgkit.feature_build - /rpgkit.feature_refactor - [Optional] /rpgkit.feature_edit - /rpgkit.build_skeleton - /rpgkit.build_data_flow - /rpgkit.design_base_classes - /rpgkit.design_interfaces - /rpgkit.plan_tasks - /rpgkit.code_gen - [Optional] /rpgkit.rpg_edit + /cmind.feature_spec + /cmind.feature_build + /cmind.feature_refactor + [Optional] /cmind.feature_edit + /cmind.build_skeleton + /cmind.build_data_flow + /cmind.design_base_classes + /cmind.design_interfaces + /cmind.plan_tasks + /cmind.code_gen + [Optional] /cmind.rpg_edit ``` > [!IMPORTANT] > **不同 Coding Agent 的调用方式略有不同**: > -> - **Claude Code**:直接在对话中输入 `/rpgkit.feature_spec ...`,slash command 会被识别并触发对应 workflow。 -> - **GitHub Copilot CLI**:不支持 slash command(但支持自定义 agent),需要先 `/agent rpgkit.feature_spec` 切换到目标 agent,然后输入 `start` 让它执行内置的 workflow。 +> - **Claude Code**:直接在对话中输入 `/cmind.feature_spec ...`,slash command 会被识别并触发对应 workflow。 +> - **GitHub Copilot CLI**:不支持 slash command(但支持自定义 agent),需要先 `/agent cmind.feature_spec` 切换到目标 agent,然后输入 `start` 让它执行内置的 workflow。 -RPG-Kit 会渐进式地在 home-side 运行时目录(`~/.rpgkit/workspaces//data/rpg.json`)里创建 `rpg.json`,并用它把需求、规划产物、生成的代码和依赖信息保持对齐。你的工作区源文件不会被污染。 +CoderMind 会渐进式地在 home-side 运行时目录(`~/.cmind/workspaces//data/rpg.json`)里创建 `rpg.json`,并用它把需求、规划产物、生成的代码和依赖信息保持对齐。你的工作区源文件不会被污染。 ## 快速开始:已有仓库 当你已经有一个仓库,希望 AI 智能体在 RPG 上下文中理解或编辑它时,使用此路径。 > [!WARNING] -> 对于较大的项目,`rpgkit init . --encode` 和 `/rpgkit.encode` 可能运行较长时间。典型例子:200 个源文件大约需要 100 分钟。 +> 对于较大的项目,`cmind init . --encode` 和 `/cmind.encode` 可能运行较长时间。典型例子:200 个源文件大约需要 100 分钟。 -1. 在仓库根目录初始化 RPG-Kit 并构建初始图: +1. 在仓库根目录初始化 CoderMind 并构建初始图: ```bash cd existing-repo/ - rpgkit init . --encode # --encode 会根据当前的代码生成 RPG + cmind init . --encode # --encode 会根据当前的代码生成 RPG ``` 如果你想跳过非空目录的确认提示: ```bash - rpgkit init . --force --encode + cmind init . --force --encode ``` 2. 在仓库里启动你的 AI 编码智能体。 @@ -179,39 +179,39 @@ RPG-Kit 会渐进式地在 home-side 运行时目录(`~/.rpgkit/workspaces/ # 图感知的代码编辑 + /cmind.encode # 需要时重建完整 RPG + /cmind.update_rpg # 手动增量更新(fallback) + /cmind.rpg_edit # 图感知的代码编辑 ``` -4. 每次 commit 后,RPG-Kit 安装的 git hook 会自动调用 `rpgkit hook ` 调度器,更新 RPG,与代码变更保持对齐。如果 hook 失败或被跳过,可以手动运行 `/rpgkit.update_rpg`。 +4. 每次 commit 后,CoderMind 安装的 git hook 会自动调用 `cmind hook ` 调度器,更新 RPG,与代码变更保持对齐。如果 hook 失败或被跳过,可以手动运行 `/cmind.update_rpg`。 -## `rpgkit init` 之后会发生什么 +## `cmind init` 之后会发生什么 -`rpgkit init` 不会修改你的源文件,**也不会在你的工作区写入运行时状态**。它只在你的工作区添加命令定义、MCP 配置和 hooks,所有 RPG-Kit 的运行时数据(产物、日志)都放在 home-side 目录 `~/.rpgkit/workspaces//` 下,其中 `` 是根据工作区绝对路径生成的可读 slug(例如 `home-hys-projects-myrepo`)。 +`cmind init` 不会修改你的源文件,**也不会在你的工作区写入运行时状态**。它只在你的工作区添加命令定义、MCP 配置和 hooks,所有 CoderMind 的运行时数据(产物、日志)都放在 home-side 目录 `~/.cmind/workspaces//` 下,其中 `` 是根据工作区绝对路径生成的可读 slug(例如 `home-hys-projects-myrepo`)。 ```text my-project/ -├── docs/ # /rpgkit.feature_spec 的可选需求文档 +├── docs/ # /cmind.feature_spec 的可选需求文档 ├── .github/ or .claude/ # AI 助手的命令定义和设置 ├── .vscode/ # 适用时的 Copilot/VS Code MCP 配置 -├── .rpgkit/ # 包含生成的报告和配置文件 -└── .git/hooks/ # rpgkit init 装的 post-commit / post-merge(每个 hook 仅一行:`rpgkit hook `) +├── .cmind/ # 包含生成的报告和配置文件 +└── .git/hooks/ # cmind init 装的 post-commit / post-merge(每个 hook 仅一行:`cmind hook `) ``` 完整的目录布局和数据文件参考见 [docs/project-structure.md](docs/project-structure.md)。 -## 更新 RPG-Kit +## 更新 CoderMind ```bash -uv tool install rpgkit-cli \ - --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" \ +uv tool install cmind-cli \ + --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" \ --force \ --reinstall # 对已有工作区进行更新 cd -rpgkit update +cmind update ``` ## 支持的平台 @@ -234,20 +234,20 @@ rpgkit update ## 文档 -- [Slash 命令参考](docs/commands.md) —— 每一个 `/rpgkit.*` 命令的输入、输出和示例。 -- [CLI 参考](docs/cli-reference.md) —— `rpgkit init`、`rpgkit update`、`rpgkit check`、`rpgkit version` 以及所有选项。 +- [Slash 命令参考](docs/commands.md) —— 每一个 `/cmind.*` 命令的输入、输出和示例。 +- [CLI 参考](docs/cli-reference.md) —— `cmind init`、`cmind update`、`cmind check`、`cmind version` 以及所有选项。 - [配置](docs/configuration.md) —— AI 助手设置、MCP 注册、hook、自动审批和故障排查。 -- [项目结构](docs/project-structure.md) —— RPG-Kit 创建的文件和目录。 +- [项目结构](docs/project-structure.md) —— CoderMind 创建的文件和目录。 ## 即将推出的功能 -- **更简化的生成命令**:把当前多步骤的生成流程合并为更少的命令,例如 `/rpgkit.generate_repo`、`/rpgkit.generate_feature` 和 `/rpgkit.plan`。 +- **更简化的生成命令**:把当前多步骤的生成流程合并为更少的命令,例如 `/cmind.generate_repo`、`/cmind.generate_feature` 和 `/cmind.plan`。 - **多语言支持**:增加对 Go、C++、Rust、JavaScript/TypeScript 等的支持。 - **更多平台集成**:在不同系统上跨 CLI 和 VS Code 扩展工作流支持不同的 AI 编码智能体。 ## 故障排查 -**找不到 AI 助手 CLI**:运行 `rpgkit check`,安装并完成所选助手 CLI 的身份验证,然后重新运行 `rpgkit init` 或 `rpgkit update`。 +**找不到 AI 助手 CLI**:运行 `cmind check`,安装并完成所选助手 CLI 的身份验证,然后重新运行 `cmind init` 或 `cmind update`。 ## 许可证 diff --git a/CoderMind/docs/cli-reference.md b/CoderMind/docs/cli-reference.md index 0385716..8c7d33c 100644 --- a/CoderMind/docs/cli-reference.md +++ b/CoderMind/docs/cli-reference.md @@ -1,15 +1,15 @@ # CLI Reference -This document covers the `rpgkit` command-line interface. Use the CLI to install templates, initialize projects, update RPG-Kit files, and verify local tool availability. +This document covers the `cmind` command-line interface. Use the CLI to install templates, initialize projects, update CoderMind files, and verify local tool availability. -## `rpgkit init` +## `cmind init` -Initialize a new project from the latest template, or add RPG-Kit to an existing repository. +Initialize a new project from the latest template, or add CoderMind to an existing repository. ```bash -rpgkit init [options] -rpgkit init --here [options] -rpgkit init . [options] +cmind init [options] +cmind init --here [options] +cmind init . [options] ``` ### Options @@ -33,28 +33,28 @@ rpgkit init . [options] | `copilot` | `.github/`, `.vscode/` | GitHub Copilot | Verified | | `claude` | `.claude/` | Claude Code | Verified | -RPG-Kit currently supports only **GitHub Copilot** and **Claude Code** in the CLI. Additional agents may be adapted in future releases. +CoderMind currently supports only **GitHub Copilot** and **Claude Code** in the CLI. Additional agents may be adapted in future releases. ### Examples ```bash -rpgkit init my-project -rpgkit init my-project --ai claude --script sh -rpgkit init . --force -rpgkit init . --encode -rpgkit init . --force --encode -rpgkit init --here --ai copilot +cmind init my-project +cmind init my-project --ai claude --script sh +cmind init . --force +cmind init . --encode +cmind init . --force --encode +cmind init --here --ai copilot ``` -## `rpgkit update` +## `cmind update` -Update RPG-Kit template files, scripts, command definitions, MCP configuration, gitignore rules, and hooks in an existing project. The AI assistant is auto-detected from existing project configuration when possible. +Update CoderMind template files, scripts, command definitions, MCP configuration, gitignore rules, and hooks in an existing project. The AI assistant is auto-detected from existing project configuration when possible. ```bash -rpgkit update -rpgkit update --ai claude -rpgkit update --no-mcp -rpgkit update --no-upgrade +cmind update +cmind update --ai claude +cmind update --no-mcp +cmind update --no-upgrade ``` ### Options @@ -69,29 +69,29 @@ rpgkit update --no-upgrade ### Auto-upgrade behaviour -Since the global-install layout, `rpgkit update` performs a **best-effort silent self-upgrade by default** when the install source is safe to refresh (git+URL or PyPI). After upgrading the CLI it re-executes itself once to continue the workspace sync with the new code. Editable installs, local-file installs, and unknown sources are skipped silently. +Since the global-install layout, `cmind update` performs a **best-effort silent self-upgrade by default** when the install source is safe to refresh (git+URL or PyPI). After upgrading the CLI it re-executes itself once to continue the workspace sync with the new code. Editable installs, local-file installs, and unknown sources are skipped silently. - Pass `--no-upgrade` to skip the upgrade entirely (useful for offline or pinned environments). -- A loop guard environment variable (`RPGKIT_UPGRADE_DONE`) is set across the re-exec to guarantee at most one upgrade attempt per invocation. +- A loop guard environment variable (`CMIND_UPGRADE_DONE`) is set across the re-exec to guarantee at most one upgrade attempt per invocation. ### Provisioning sources -As of `0.1.4`, `rpgkit init` and `rpgkit update` provision exclusively +As of `0.1.4`, `cmind init` and `cmind update` provision exclusively from the **packaged assets bundle** shipped inside the installed -`rpgkit-cli` wheel (under `rpgkit_cli/core_pack/`). No network access +`cmind-cli` wheel (under `cmind_cli/core_pack/`). No network access is required at provisioning time. To pick up newer prompts and templates, upgrade the CLI itself -(e.g. `uv tool upgrade rpgkit-cli`). `rpgkit update` does this +(e.g. `uv tool upgrade cmind-cli`). `cmind update` does this automatically by default (see *Auto-upgrade behaviour* above); pass `--no-upgrade` to opt out. -## `rpgkit check` +## `cmind check` -Verify that the local environment has the tools RPG-Kit relies on. +Verify that the local environment has the tools CoderMind relies on. ```bash -rpgkit check +cmind check ``` Probes for Git, the supported AI assistant CLIs (GitHub Copilot, @@ -100,23 +100,23 @@ prints a tree of which ones are available. Run this after installation to confirm the environment is ready, or whenever a pipeline step complains about a missing tool. -## `rpgkit version` +## `cmind version` Display version and system information. ```bash -rpgkit version +cmind version ``` -## `rpgkit script` +## `cmind script` -Execute one of the bundled RPG-Kit pipeline scripts. After install -(`uv tool install rpgkit-cli`) the scripts live inside the wheel under -`rpgkit_cli/core_pack/scripts/` and are no longer copied into each +Execute one of the bundled CoderMind pipeline scripts. After install +(`uv tool install cmind-cli`) the scripts live inside the wheel under +`cmind_cli/core_pack/scripts/` and are no longer copied into each workspace; this command is the supported way to invoke them. ```bash -rpgkit script [args...] +cmind script [args...] ``` Arguments after `` are forwarded verbatim to the target @@ -134,18 +134,18 @@ and absolute paths are rejected for safety. ### Examples ```bash -rpgkit script smoke_test.py --json -rpgkit script rpg_edit/validate.py -rpgkit script --list -rpgkit script --where mcp_server.py +cmind script smoke_test.py --json +cmind script rpg_edit/validate.py +cmind script --list +cmind script --where mcp_server.py ``` -The slash-command templates installed by `rpgkit init` (in -`.claude/commands/` or `.github/agents/`) all use `rpgkit script …` +The slash-command templates installed by `cmind init` (in +`.claude/commands/` or `.github/agents/`) all use `cmind script …` under the hood, so AI agents invoke the pipeline through the same contract. -A companion console script, `rpgkit-mcp`, is the MCP server entry +A companion console script, `cmind-mcp`, is the MCP server entry point and is what `.mcp.json` / `.vscode/mcp.json` register as the `rpg-tools` command — no absolute paths in the config, no per-machine edits. diff --git a/CoderMind/docs/commands.md b/CoderMind/docs/commands.md index 9f712c9..f434af2 100644 --- a/CoderMind/docs/commands.md +++ b/CoderMind/docs/commands.md @@ -1,12 +1,12 @@ -# /rpgkit Commands Reference +# /cmind Commands Reference -RPG-Kit provides 13 slash commands that work in three paths: +CoderMind provides 13 slash commands that work in three paths: - **Forward pipeline:** Requirements → Repository Planning Graph (RPG) → Code - **Reverse encoder:** Existing code → RPG - **Surgical edit:** Natural-language changes applied to code, RPG, and dependency graph together -> **Note on data paths.** Throughout this document, paths shown as `.rpgkit/data/...` and `.rpgkit/logs/...` are stable logical names. The actual files live **outside the workspace** under `~/.rpgkit/workspaces//{data,logs}/`, where `` is a slug-based identifier and may include an overflow `-` suffix, so that runtime artefacts never enter the user's git repository. Reports (`rpg.html`, review HTML, etc.) stay in the workspace at `/.rpgkit/reports/` because they are small user-facing artefacts users may want to commit. Run `rpgkit version` from inside the workspace to see the resolved Data / Logs paths. See [project-structure.md](project-structure.md) for the full layout. +> **Note on data paths.** Throughout this document, paths shown as `.cmind/data/...` and `.cmind/logs/...` are stable logical names. The actual files live **outside the workspace** under `~/.cmind/workspaces//{data,logs}/`, where `` is a slug-based identifier and may include an overflow `-` suffix, so that runtime artefacts never enter the user's git repository. Reports (`rpg.html`, review HTML, etc.) stay in the workspace at `/.cmind/reports/` because they are small user-facing artefacts users may want to commit. Run `cmind version` from inside the workspace to see the resolved Data / Logs paths. See [project-structure.md](project-structure.md) for the full layout. ## Command Overview @@ -14,42 +14,42 @@ RPG-Kit provides 13 slash commands that work in three paths: | Command | Description | | ------- | ----------- | -| `/rpgkit.feature_spec ` | Create structured feature specifications from user input or `docs/` files | -| `/rpgkit.feature_build` | Generate and expand the feature tree from specifications | -| `/rpgkit.feature_refactor` | Refactor feature tree into modular component architecture | -| `/rpgkit.feature_edit ` | Edit feature tree nodes before skeleton planning — optional | +| `/cmind.feature_spec ` | Create structured feature specifications from user input or `docs/` files | +| `/cmind.feature_build` | Generate and expand the feature tree from specifications | +| `/cmind.feature_refactor` | Refactor feature tree into modular component architecture | +| `/cmind.feature_edit ` | Edit feature tree nodes before skeleton planning — optional | ### Phase 2: RPG Construction and Planning | Command | Description | | ------- | ----------- | -| `/rpgkit.build_skeleton` | Build repository file skeleton from component architecture; creates `.rpgkit/data/rpg.json` | -| `/rpgkit.build_data_flow` | Build inter-component data flow DAG and update the RPG | -| `/rpgkit.design_base_classes` | Design shared base classes and data structures | -| `/rpgkit.design_interfaces` | Design function/class interfaces with type hints and docstrings | -| `/rpgkit.plan_tasks` | Plan dependency-ordered implementation task batches | +| `/cmind.build_skeleton` | Build repository file skeleton from component architecture; creates `.cmind/data/rpg.json` | +| `/cmind.build_data_flow` | Build inter-component data flow DAG and update the RPG | +| `/cmind.design_base_classes` | Design shared base classes and data structures | +| `/cmind.design_interfaces` | Design function/class interfaces with type hints and docstrings | +| `/cmind.plan_tasks` | Plan dependency-ordered implementation task batches | ### Phase 3: Code Generation and Surgical Edits | Command | Description | | ------- | ----------- | -| `/rpgkit.code_gen` | TDD-based implementation with iterative test-code-fix cycles | -| `/rpgkit.rpg_edit ` | Surgical edit of RPG graph, code, and dependency graph from a natural-language instruction — optional | +| `/cmind.code_gen` | TDD-based implementation with iterative test-code-fix cycles | +| `/cmind.rpg_edit ` | Surgical edit of RPG graph, code, and dependency graph from a natural-language instruction — optional | ### RPG Encoder: Code to RPG | Command | Description | | ------- | ----------- | -| `/rpgkit.encode` | Encode an existing repository into `.rpgkit/data/rpg.json` | -| `/rpgkit.update_rpg` | Manually run incremental RPG update when the automatic hook is skipped or fails | +| `/cmind.encode` | Encode an existing repository into `.cmind/data/rpg.json` | +| `/cmind.update_rpg` | Manually run incremental RPG update when the automatic hook is skipped or fails | -Both directions produce the same RPG structure at `.rpgkit/data/rpg.json`, enabling AI agents to query the graph via the **MCP server** (`search_rpg`, `explore_rpg`, `get_node_detail`, `list_rpg_tree`). See [configuration.md](configuration.md) for MCP details. +Both directions produce the same RPG structure at `.cmind/data/rpg.json`, enabling AI agents to query the graph via the **MCP server** (`search_rpg`, `explore_rpg`, `get_node_detail`, `list_rpg_tree`). See [configuration.md](configuration.md) for MCP details. --- ## Phase 1: Feature Specification -### `/rpgkit.feature_spec` +### `/cmind.feature_spec` Create structured feature specifications from user input or documentation files. @@ -61,7 +61,7 @@ Create structured feature specifications from user input or documentation files. **Output:** ```text -.rpgkit/data/feature_spec/ +.cmind/data/feature_spec/ ├── evidence/ # Source evidence files │ ├── user_input.md # From direct user input, or │ ├── 01_project_charter.md @@ -73,31 +73,31 @@ Create structured feature specifications from user input or documentation files. └── ... ``` -Also generates `.rpgkit/data/feature_spec.json`. +Also generates `.cmind/data/feature_spec.json`. **Examples:** ```text -/rpgkit.feature_spec Build a CLI tool for managing Docker containers -/rpgkit.feature_spec # Auto-detect docs/ files +/cmind.feature_spec Build a CLI tool for managing Docker containers +/cmind.feature_spec # Auto-detect docs/ files ``` --- -### `/rpgkit.feature_build` +### `/cmind.feature_build` -Generate and iteratively refine the feature tree from `.rpgkit/data/feature_spec.json`. +Generate and iteratively refine the feature tree from `.cmind/data/feature_spec.json`. -**Input:** `.rpgkit/data/feature_spec.json` +**Input:** `.cmind/data/feature_spec.json` -**Output:** `.rpgkit/data/feature_build.json` +**Output:** `.cmind/data/feature_build.json` **Current workflow:** -1. **Validate status** — runs `rpgkit script feature_build_validation.py` to verify that `feature_spec.json` exists and decide whether this is a first build or an expansion. -2. **Build or expand** — runs `rpgkit script feature_build.py --mode step1`. - - If `feature_build.json` does not exist, RPG-Kit builds the feature tree from the specification and iterates until requirements are covered. - - If `feature_build.json` already exists, RPG-Kit switches to beyond-spec expansion mode and adds production-relevant features not described by the original spec. +1. **Validate status** — runs `cmind script feature_build_validation.py` to verify that `feature_spec.json` exists and decide whether this is a first build or an expansion. +2. **Build or expand** — runs `cmind script feature_build.py --mode step1`. + - If `feature_build.json` does not exist, CoderMind builds the feature tree from the specification and iterates until requirements are covered. + - If `feature_build.json` already exists, CoderMind switches to beyond-spec expansion mode and adds production-relevant features not described by the original spec. 3. **Review** — validates coverage, duplicates, and MIU constraints. Coverage review uses a default threshold of `98.0` and up to `3` review iterations. 4. **Optional user-guided expansion** — the agent can ask whether to suggest additional expansion directions, then run `--mode suggest-directions` and `--mode step2 --direction `. @@ -106,18 +106,18 @@ The spec-driven expansion loop has a hard safety cap of 20 iterations; the model **Examples:** ```text -/rpgkit.feature_build +/cmind.feature_build ``` --- -### `/rpgkit.feature_refactor` +### `/cmind.feature_refactor` Refactor the feature tree into a modular component architecture. -**Input:** `.rpgkit/data/feature_build.json` +**Input:** `.cmind/data/feature_build.json` -**Output:** `.rpgkit/data/feature_tree.json` +**Output:** `.cmind/data/feature_tree.json` **Process:** @@ -127,16 +127,16 @@ Refactor the feature tree into a modular component architecture. **Example:** ```text -/rpgkit.feature_refactor +/cmind.feature_refactor ``` --- -### `/rpgkit.feature_edit` +### `/cmind.feature_edit` Edit feature tree nodes before repository planning begins. -**Input/Output:** `.rpgkit/data/feature_tree.json` +**Input/Output:** `.cmind/data/feature_tree.json` **Supported edits:** add, delete, modify, expand, move, or merge feature tree nodes. @@ -149,27 +149,27 @@ Edit feature tree nodes before repository planning begins. **Examples:** ```text -/rpgkit.feature_edit Delete the 'cloud integration' component -/rpgkit.feature_edit Add logging features under 'cli operations' -/rpgkit.feature_edit Expand the 'security' component with encryption options -/rpgkit.feature_edit Merge 'analytics telemetry' into 'monitoring observability' +/cmind.feature_edit Delete the 'cloud integration' component +/cmind.feature_edit Add logging features under 'cli operations' +/cmind.feature_edit Expand the 'security' component with encryption options +/cmind.feature_edit Merge 'analytics telemetry' into 'monitoring observability' ``` --- ## Phase 2: RPG Construction and Planning -### `/rpgkit.build_skeleton` +### `/cmind.build_skeleton` Build the repository file skeleton from the component architecture. This is where the forward pipeline first creates the RPG. -**Input:** `.rpgkit/data/feature_tree.json` +**Input:** `.cmind/data/feature_tree.json` **Output:** -- `.rpgkit/data/skeleton.json` — file skeleton -- `.rpgkit/data/skeleton_summary.txt` — human-readable skeleton summary -- `.rpgkit/data/rpg.json` — initial Repository Planning Graph with file and feature nodes +- `.cmind/data/skeleton.json` — file skeleton +- `.cmind/data/skeleton_summary.txt` — human-readable skeleton summary +- `.cmind/data/rpg.json` — initial Repository Planning Graph with file and feature nodes **Process:** @@ -179,23 +179,23 @@ Build the repository file skeleton from the component architecture. This is wher **Examples:** ```text -/rpgkit.build_skeleton -/rpgkit.build_skeleton Prefer flat directory structure +/cmind.build_skeleton +/cmind.build_skeleton Prefer flat directory structure ``` --- -### `/rpgkit.build_data_flow` +### `/cmind.build_data_flow` Build inter-component data flow as a directed acyclic graph (DAG). -**Input:** `.rpgkit/data/skeleton.json`, `.rpgkit/data/feature_tree.json` +**Input:** `.cmind/data/skeleton.json`, `.cmind/data/feature_tree.json` **Output:** -- `.rpgkit/data/data_flow.json` — data flow DAG -- `.rpgkit/data/data_flow_viz.html` — interactive visualization -- Updates `.rpgkit/data/rpg.json` — adds data-flow edges +- `.cmind/data/data_flow.json` — data flow DAG +- `.cmind/data/data_flow_viz.html` — interactive visualization +- Updates `.cmind/data/rpg.json` — adds data-flow edges **Process:** @@ -203,29 +203,29 @@ Build inter-component data flow as a directed acyclic graph (DAG). 2. **Iteration choice** — asks for max iterations: - `Y` uses the default of 5 iterations. - A number sets a custom iteration budget. -3. **DAG design** — runs `rpgkit script build_data_flow.py --max-iterations `. -4. **Validation** — runs `rpgkit script check_data_flow.py --verbose`. -5. **Visualization** — runs `rpgkit script generate_viz.py` when a new data flow is built. +3. **DAG design** — runs `cmind script build_data_flow.py --max-iterations `. +4. **Validation** — runs `cmind script check_data_flow.py --verbose`. +5. **Visualization** — runs `cmind script generate_viz.py` when a new data flow is built. **Example:** ```text -/rpgkit.build_data_flow -/rpgkit.build_data_flow Make the ingestion layer independent from reporting +/cmind.build_data_flow +/cmind.build_data_flow Make the ingestion layer independent from reporting ``` --- -### `/rpgkit.design_base_classes` +### `/cmind.design_base_classes` Design shared base classes and global data structures to improve modularity and reuse. -**Input:** `.rpgkit/data/skeleton.json`, `.rpgkit/data/data_flow.json` +**Input:** `.cmind/data/skeleton.json`, `.cmind/data/data_flow.json` **Output:** -- `.rpgkit/data/base_classes.json` — base class and global data structure definitions -- Updates `.rpgkit/data/rpg.json` — adds base-class relationship edges +- `.cmind/data/base_classes.json` — base class and global data structure definitions +- Updates `.cmind/data/rpg.json` — adds base-class relationship edges **Process:** @@ -242,21 +242,21 @@ Design shared base classes and global data structures to improve modularity and **Example:** ```text -/rpgkit.design_base_classes +/cmind.design_base_classes ``` --- -### `/rpgkit.design_interfaces` +### `/cmind.design_interfaces` Design function and class interfaces with type hints and docstrings for all planned repository files. -**Input:** `.rpgkit/data/skeleton.json`, `.rpgkit/data/data_flow.json`, `.rpgkit/data/base_classes.json` +**Input:** `.cmind/data/skeleton.json`, `.cmind/data/data_flow.json`, `.cmind/data/base_classes.json` **Output:** -- `.rpgkit/data/interfaces.json` — function/class interface definitions -- Updates `.rpgkit/data/rpg.json` — adds fine-grained dependency edges such as inheritance, invocation, and references +- `.cmind/data/interfaces.json` — function/class interface definitions +- Updates `.cmind/data/rpg.json` — adds fine-grained dependency edges such as inheritance, invocation, and references **Process:** @@ -268,18 +268,18 @@ Design function and class interfaces with type hints and docstrings for all plan **Example:** ```text -/rpgkit.design_interfaces +/cmind.design_interfaces ``` --- -### `/rpgkit.plan_tasks` +### `/cmind.plan_tasks` Plan implementation tasks from interface definitions, organized into dependency-ordered batches. -**Input:** `.rpgkit/data/interfaces.json`, `.rpgkit/data/data_flow.json`, `.rpgkit/data/rpg.json` +**Input:** `.cmind/data/interfaces.json`, `.cmind/data/data_flow.json`, `.cmind/data/rpg.json` -**Output:** `.rpgkit/data/tasks.json` +**Output:** `.cmind/data/tasks.json` **Process:** @@ -291,20 +291,20 @@ Plan implementation tasks from interface definitions, organized into dependency- **Example:** ```text -/rpgkit.plan_tasks +/cmind.plan_tasks ``` --- ## Phase 3: Code Generation and Surgical Edits -### `/rpgkit.code_gen` +### `/cmind.code_gen` Execute TDD-based code implementation with iterative test-code-fix cycles. -**Input:** `.rpgkit/data/tasks.json`, `.rpgkit/data/interfaces.json`, `.rpgkit/data/base_classes.json`, `.rpgkit/data/data_flow.json`, `.rpgkit/data/rpg.json` +**Input:** `.cmind/data/tasks.json`, `.cmind/data/interfaces.json`, `.cmind/data/base_classes.json`, `.cmind/data/data_flow.json`, `.cmind/data/rpg.json` -**Output:** complete tested source code, `.rpgkit/data/code_gen_state.jsonl`, and updated `.rpgkit/data/rpg.json` +**Output:** complete tested source code, `.cmind/data/code_gen_state.jsonl`, and updated `.cmind/data/rpg.json` **Batch modes:** @@ -335,35 +335,35 @@ Execute TDD-based code implementation with iterative test-code-fix cycles. **Example:** ```text -/rpgkit.code_gen +/cmind.code_gen ``` --- -### `/rpgkit.rpg_edit` +### `/cmind.rpg_edit` Apply a natural-language edit to code, RPG, and dependency graph in sync. -This command is independent from `/rpgkit.feature_edit` and `/rpgkit.update_rpg`. It does not edit `feature_tree.json`; it uses the current RPG feature graph as the authoritative entry point for code modifications. +This command is independent from `/cmind.feature_edit` and `/cmind.update_rpg`. It does not edit `feature_tree.json`; it uses the current RPG feature graph as the authoritative entry point for code modifications. **Input:** edit instruction after the command -**Input files:** `.rpgkit/data/rpg.json`, `.rpgkit/data/dep_graph.json` +**Input files:** `.cmind/data/rpg.json`, `.cmind/data/dep_graph.json` **Generated files:** -- `.rpgkit/data/rpg_edit_impact.json` — impact analysis output -- `.rpgkit/data/rpg_edit_plan.json` — user-confirmed edit plan -- `.rpgkit/data/rpg_edit_code_result.json` — code application result +- `.cmind/data/rpg_edit_impact.json` — impact analysis output +- `.cmind/data/rpg_edit_plan.json` — user-confirmed edit plan +- `.cmind/data/rpg_edit_code_result.json` — code application result **Workflow:** -1. **Pre-check** — runs `rpgkit script rpg_edit/validate.py --json` and stops if the RPG or dependency graph is unavailable. -2. **Locate target nodes** — runs `rpgkit script rpg_edit/locate.py --query "" --json` and selects existing nodes or nearest parent nodes for new features. -3. **Analyze impact** — runs `rpgkit script rpg_edit/impact.py --node-id ... --json` to identify affected nodes, callers, callees, and files. +1. **Pre-check** — runs `cmind script rpg_edit/validate.py --json` and stops if the RPG or dependency graph is unavailable. +2. **Locate target nodes** — runs `cmind script rpg_edit/locate.py --query "" --json` and selects existing nodes or nearest parent nodes for new features. +3. **Analyze impact** — runs `cmind script rpg_edit/impact.py --node-id ... --json` to identify affected nodes, callers, callees, and files. 4. **Optional visual reconnaissance** — for UI/layout/style edits, probes the app with the browser helper when available. 5. **Mandatory code reconnaissance** — reads affected files and searches related patterns before producing a plan. -6. **Generate and confirm plan** — writes `.rpgkit/data/rpg_edit_plan.json` and asks the user to apply, cancel, revise, or inspect a node. +6. **Generate and confirm plan** — writes `.cmind/data/rpg_edit_plan.json` and asks the user to apply, cancel, revise, or inspect a node. 7. **Apply on a branch** — creates a `rpg-edit/` branch only after a clean working-tree preflight. 8. **RPG-first apply** — updates RPG feature changes first, then dispatches code changes, refreshes `dep_graph.json`, and folds graph updates into the branch commit. 9. **Test and review** — runs smoke tests and impact review. @@ -372,76 +372,76 @@ This command is independent from `/rpgkit.feature_edit` and `/rpgkit.update_rpg` **Examples:** ```text -/rpgkit.rpg_edit Add a last_login field to the User model and update it on login -/rpgkit.rpg_edit Add rate limiting to all API endpoints -/rpgkit.rpg_edit Refactor auth into separate registration and login modules +/cmind.rpg_edit Add a last_login field to the User model and update it on login +/cmind.rpg_edit Add rate limiting to all API endpoints +/cmind.rpg_edit Refactor auth into separate registration and login modules ``` --- ## RPG Encoder: Code to RPG -The encoder works in the reverse direction from the forward pipeline. It takes an existing codebase and produces the same Repository Planning Graph structure used by RPG-Kit's planning, editing, and MCP tooling. +The encoder works in the reverse direction from the forward pipeline. It takes an existing codebase and produces the same Repository Planning Graph structure used by CoderMind's planning, editing, and MCP tooling. -### `/rpgkit.encode` +### `/cmind.encode` Encode the current repository into an RPG from scratch. **Output:** -- `.rpgkit/data/rpg.json` — Repository Planning Graph -- `.rpgkit/data/dep_graph.json` — code dependency graph used for incremental sync and edits +- `.cmind/data/rpg.json` — Repository Planning Graph +- `.cmind/data/dep_graph.json` — code dependency graph used for incremental sync and edits **Process:** -1. **Pre-check** — runs `rpgkit script rpg_encoder/check_encode.py --json`. -2. **Full encode** — runs `rpgkit script rpg_encoder/run_encode.py --json`. -3. **Next steps** — suggests `/rpgkit.update_rpg` for incremental updates and MCP tools for exploration. +1. **Pre-check** — runs `cmind script rpg_encoder/check_encode.py --json`. +2. **Full encode** — runs `cmind script rpg_encoder/run_encode.py --json`. +3. **Next steps** — suggests `/cmind.update_rpg` for incremental updates and MCP tools for exploration. -If `rpg.json` already exists, the command asks whether to full re-encode, switch to `/rpgkit.update_rpg`, or quit. +If `rpg.json` already exists, the command asks whether to full re-encode, switch to `/cmind.update_rpg`, or quit. **Example:** ```text -/rpgkit.encode +/cmind.encode ``` --- -### `/rpgkit.update_rpg` +### `/cmind.update_rpg` Manually trigger an incremental RPG update when the automatic hook did not run or when the user wants an immediate foreground update. -Under normal use, RPG-Kit installs a post-commit hook that updates the RPG in the background after each commit. This command is the manual fallback. +Under normal use, CoderMind installs a post-commit hook that updates the RPG in the background after each commit. This command is the manual fallback. -**Input:** existing `.rpgkit/data/rpg.json` and a git repository with at least two commits +**Input:** existing `.cmind/data/rpg.json` and a git repository with at least two commits -**Output:** updated `.rpgkit/data/rpg.json` and `.rpgkit/data/dep_graph.json` +**Output:** updated `.cmind/data/rpg.json` and `.cmind/data/dep_graph.json` **Process:** -1. **Pre-check** — runs `rpgkit script rpg_encoder/check_encode.py --json` and stops if `rpg.json` is missing or corrupt. -2. **Commit baseline check** — verifies `HEAD~1` exists. If there is no previous commit, run `/rpgkit.encode` instead. -3. **Incremental update** — runs `rpgkit script update_graphs.py update-rpg --json`, comparing the current workspace against `HEAD~1`, the same baseline used by the hook. +1. **Pre-check** — runs `cmind script rpg_encoder/check_encode.py --json` and stops if `rpg.json` is missing or corrupt. +2. **Commit baseline check** — verifies `HEAD~1` exists. If there is no previous commit, run `/cmind.encode` instead. +3. **Incremental update** — runs `cmind script update_graphs.py update-rpg --json`, comparing the current workspace against `HEAD~1`, the same baseline used by the hook. 4. **Report result** — displays node/edge deltas, functional areas, alignment status, and output path. Use this command when: - The post-commit hook failed or was skipped. -- `.rpgkit/logs/update_rpg.log` shows an error. +- `.cmind/logs/update_rpg.log` shows an error. - The RPG seems stale and you want to force a synchronous update. **Example:** ```text -/rpgkit.update_rpg +/cmind.update_rpg ``` --- ## MCP Server Tools -RPG-Kit registers an MCP server named `rpg-tools` so AI agents can query `.rpgkit/data/rpg.json` during chat. The server exposes four read-only tools: +CoderMind registers an MCP server named `rpg-tools` so AI agents can query `.cmind/data/rpg.json` during chat. The server exposes four read-only tools: | Tool | Description | | ---- | ----------- | @@ -450,7 +450,7 @@ RPG-Kit registers an MCP server named `rpg-tools` so AI agents can query `.rpgki | `get_node_detail` | Fetch full details for a function, class, file, or feature node | | `list_rpg_tree` | Render the functional architecture as a tree | -If `.rpgkit/data/rpg.json` is not available yet, the tools return an `rpg_unavailable` response that asks the agent to run `/rpgkit.encode`. +If `.cmind/data/rpg.json` is not available yet, the tools return an `rpg_unavailable` response that asks the agent to run `/cmind.encode`. See [configuration.md](configuration.md) for MCP registration, auto-approval, hooks, and initialization options. @@ -458,7 +458,7 @@ See [configuration.md](configuration.md) for MCP registration, auto-approval, ho ## Data Files -All intermediate data is stored in `.rpgkit/data/`: +All intermediate data is stored in `.cmind/data/`: | File | Produced by | Description | | ---- | ----------- | ----------- | @@ -485,8 +485,8 @@ All intermediate data is stored in `.rpgkit/data/`: `rpg.json` is the central artifact that ties the pipeline together. It can be created in either direction: -1. **Forward:** `/rpgkit.build_skeleton` creates it from `feature_tree.json`; later planning and generation commands enrich it. -2. **Reverse:** `/rpgkit.encode` creates it from an existing codebase; `/rpgkit.update_rpg` keeps it aligned after commits. +1. **Forward:** `/cmind.build_skeleton` creates it from `feature_tree.json`; later planning and generation commands enrich it. +2. **Reverse:** `/cmind.encode` creates it from an existing codebase; `/cmind.update_rpg` keeps it aligned after commits. Subsequent commands update the same file: diff --git a/CoderMind/docs/configuration.md b/CoderMind/docs/configuration.md index 1f7297e..8272f35 100644 --- a/CoderMind/docs/configuration.md +++ b/CoderMind/docs/configuration.md @@ -1,12 +1,12 @@ # Configuration -This document covers RPG-Kit configuration that is useful after installation: AI assistant setup, MCP registration, auto-approval, hooks, and initial encoding. +This document covers CoderMind configuration that is useful after installation: AI assistant setup, MCP registration, auto-approval, hooks, and initial encoding. -> **Data paths.** References below such as `.rpgkit/data/rpg.json` and `.rpgkit/logs/...` are logical names. Runtime files actually live under `~/.rpgkit/workspaces//{data,logs}/` so they stay outside your git repo, where `` is the slug-based workspace identifier used by the home-side store (with an optional `-` suffix when needed). Reports stay in the workspace at `/.rpgkit/reports/`. The MCP server, hooks, and pipeline scripts all resolve the home-dir location automatically from the workspace root. Run `rpgkit version` from inside the workspace to see the resolved Data / Logs paths; see [project-structure.md](project-structure.md) for the full layout. +> **Data paths.** References below such as `.cmind/data/rpg.json` and `.cmind/logs/...` are logical names. Runtime files actually live under `~/.cmind/workspaces//{data,logs}/` so they stay outside your git repo, where `` is the slug-based workspace identifier used by the home-side store (with an optional `-` suffix when needed). Reports stay in the workspace at `/.cmind/reports/`. The MCP server, hooks, and pipeline scripts all resolve the home-dir location automatically from the workspace root. Run `cmind version` from inside the workspace to see the resolved Data / Logs paths; see [project-structure.md](project-structure.md) for the full layout. ## AI Assistant CLI Requirements -RPG-Kit slash commands are executed by an AI coding agent. Before running `rpgkit init`, install and authenticate at least one supported AI assistant CLI. +CoderMind slash commands are executed by an AI coding agent. Before running `cmind init`, install and authenticate at least one supported AI assistant CLI. Currently verified assistants: @@ -15,25 +15,25 @@ Currently verified assistants: | GitHub Copilot | `copilot` | `.github/`, `.vscode/` | Copilot CLI available and authenticated | | Claude Code | `claude` | `.claude/` | Claude Code CLI available and authenticated | -Use `rpgkit check` to verify required local tools. +Use `cmind check` to verify required local tools. ```bash -rpgkit check +cmind check ``` -If the selected AI assistant is not found, install and authenticate it, then rerun `rpgkit init` or `rpgkit update`. +If the selected AI assistant is not found, install and authenticate it, then rerun `cmind init` or `cmind update`. -## Workspace Configuration (`.rpgkit/config.toml`) +## Workspace Configuration (`.cmind/config.toml`) -Since `0.1.3`, every workspace owns a `.rpgkit/config.toml` file that records which AI CLI command the pipeline scripts should invoke. This decouples the scripts from a single AI at packaging time — the same packaged scripts now serve any AI you pick. +Since `0.1.3`, every workspace owns a `.cmind/config.toml` file that records which AI CLI command the pipeline scripts should invoke. This decouples the scripts from a single AI at packaging time — the same packaged scripts now serve any AI you pick. ```toml -# .rpgkit/config.toml -[rpgkit] +# .cmind/config.toml +[cmind] ai_cli_cmd = "claude" ``` -The file is created automatically by `rpgkit init --ai `. Edit it any time to switch the workspace to a different AI; no need to re-run `init`. +The file is created automatically by `cmind init --ai `. Edit it any time to switch the workspace to a different AI; no need to re-run `init`. ### Resolution priority @@ -42,11 +42,11 @@ When a pipeline script (or a hook, or the MCP server) needs to invoke the AI CLI | # | Source | Use case | | - | ------ | -------- | | P1 | `LLMClient(tool="...")` constructor argument | Programmatic override (rare) | -| P2 | `RPGKIT_AI_CLI_CMD` environment variable | CI runs, one-off experiments | -| P3 | `.rpgkit/config.toml` `[rpgkit].ai_cli_cmd` | Normal default (per workspace) | +| P2 | `CMIND_AI_CLI_CMD` environment variable | CI runs, one-off experiments | +| P3 | `.cmind/config.toml` `[cmind].ai_cli_cmd` | Normal default (per workspace) | | P4 | Release-zip baked-in literal | Legacy workspaces provisioned before v0.1.4 | -If all four resolve to empty, the next `LLMClient.generate()` call raises a `RuntimeError` instructing the user to run `rpgkit init` or set the env var. +If all four resolve to empty, the next `LLMClient.generate()` call raises a `RuntimeError` instructing the user to run `cmind init` or set the env var. ### Supported AI CLI commands @@ -70,71 +70,71 @@ Only `copilot` and `claude` are currently verified end-to-end; the others are sc ### Other config keys -The `[rpgkit]` table currently holds only `ai_cli_cmd`. Future releases will add timeouts, retry budgets, and model overrides under the same namespace; older keys remain forward-compatible. +The `[cmind]` table currently holds only `ai_cli_cmd`. Future releases will add timeouts, retry budgets, and model overrides under the same namespace; older keys remain forward-compatible. ## Initialization Options ### AI assistant selection ```bash -rpgkit init my-project --ai claude -rpgkit init my-project --ai copilot +cmind init my-project --ai claude +cmind init my-project --ai copilot ``` -If `--ai` is omitted in an interactive terminal, RPG-Kit prompts for a supported assistant. +If `--ai` is omitted in an interactive terminal, CoderMind prompts for a supported assistant. ### Script type ```bash -rpgkit init my-project --script sh -rpgkit init my-project --script ps +cmind init my-project --script sh +cmind init my-project --script ps ``` `sh` installs POSIX shell-oriented command snippets. `ps` installs PowerShell-oriented snippets. ### MCP registration -By default, `rpgkit init` registers the RPG-Kit MCP server for the selected assistant. +By default, `cmind init` registers the CoderMind MCP server for the selected assistant. ```bash -rpgkit init my-project +cmind init my-project ``` Pass `--no-mcp` to skip MCP registration: ```bash -rpgkit init my-project --no-mcp -rpgkit update --no-mcp +cmind init my-project --no-mcp +cmind update --no-mcp ``` Skipping MCP means the slash-command pipeline still works, but the AI assistant will not get the `rpg-tools` graph-query tools automatically. ### Initial encode -The MCP tools query `.rpgkit/data/rpg.json`. For existing codebases, that file is created by the encoder. +The MCP tools query `.cmind/data/rpg.json`. For existing codebases, that file is created by the encoder. -`rpgkit init` supports: +`cmind init` supports: ```bash -rpgkit init --here --encode -rpgkit init --here --no-encode +cmind init --here --encode +cmind init --here --no-encode ``` Behavior: - `--encode` runs the encoder at the end of init without prompting. - `--no-encode` skips the encoder prompt. -- If neither flag is provided, RPG-Kit may prompt in an interactive terminal when Python code is present. +- If neither flag is provided, CoderMind may prompt in an interactive terminal when Python code is present. You can always run the encoder later from the AI assistant: ```text -/rpgkit.encode +/cmind.encode ``` ## MCP Server -RPG-Kit's MCP server is named `rpg-tools`. It reads `.rpgkit/data/rpg.json` and exposes read-only graph-query tools to the AI assistant. +CoderMind's MCP server is named `rpg-tools`. It reads `.cmind/data/rpg.json` and exposes read-only graph-query tools to the AI assistant. | Tool | Purpose | | ---- | ------- | @@ -143,29 +143,29 @@ RPG-Kit's MCP server is named `rpg-tools`. It reads `.rpgkit/data/rpg.json` and | `get_node_detail` | Fetch details for a specific node, optionally including source code | | `list_rpg_tree` | Render the functional architecture as a tree | -If `.rpgkit/data/rpg.json` does not exist yet, the tools return an `rpg_unavailable` response with a next step telling the agent to run `/rpgkit.encode`. +If `.cmind/data/rpg.json` does not exist yet, the tools return an `rpg_unavailable` response with a next step telling the agent to run `/cmind.encode`. ## Assistant Configuration Files ### Claude Code -For Claude Code, RPG-Kit writes command definitions and settings under `.claude/`: +For Claude Code, CoderMind writes command definitions and settings under `.claude/`: ```text .claude/ -├── commands/ # /rpgkit.* command definitions +├── commands/ # /cmind.* command definitions └── settings.json # permissions and MCP auto-approval ``` -The settings file grants project-scoped permissions needed by RPG-Kit commands, including access to the `rpg-tools` MCP server. Review `.claude/settings.json` if your team wants stricter local permission prompts. +The settings file grants project-scoped permissions needed by CoderMind commands, including access to the `rpg-tools` MCP server. Review `.claude/settings.json` if your team wants stricter local permission prompts. ### GitHub Copilot / VS Code -For Copilot, RPG-Kit writes agent instructions under `.github/` and VS Code MCP configuration under `.vscode/`: +For Copilot, CoderMind writes agent instructions under `.github/` and VS Code MCP configuration under `.vscode/`: ```text .github/ -├── agents/ # rpgkit.* agent definitions +├── agents/ # cmind.* agent definitions └── prompts/ # companion prompts .vscode/ └── mcp.json # rpg-tools registration @@ -175,31 +175,31 @@ Open the project in VS Code after initialization so the workspace MCP configurat ## Auto-approval and Scope -RPG-Kit pre-authorizes the `rpg-tools` MCP server where the selected assistant supports project-scoped permissions. The goal is to avoid prompting on every graph query during chat. +CoderMind pre-authorizes the `rpg-tools` MCP server where the selected assistant supports project-scoped permissions. The goal is to avoid prompting on every graph query during chat. Scope rules: -- Configuration is written into the project that ran `rpgkit init` or `rpgkit update`. +- Configuration is written into the project that ran `cmind init` or `cmind update`. - User-level assistant settings are not modified. - Passing `--no-mcp` skips MCP registration and related auto-approval entries. ## Git Hooks and Incremental Updates -RPG-Kit installs local git hooks to keep the RPG aligned with code changes. +CoderMind installs local git hooks to keep the RPG aligned with code changes. The important hook behavior is: -- After commits, RPG-Kit can run an incremental update in the background. -- The update refreshes `.rpgkit/data/rpg.json` and `.rpgkit/data/dep_graph.json`. -- Logs are written to `.rpgkit/logs/update_rpg.log`. +- After commits, CoderMind can run an incremental update in the background. +- The update refreshes `.cmind/data/rpg.json` and `.cmind/data/dep_graph.json`. +- Logs are written to `.cmind/logs/update_rpg.log`. Manual fallback: ```text -/rpgkit.update_rpg +/cmind.update_rpg ``` -Use `/rpgkit.update_rpg` when: +Use `/cmind.update_rpg` when: - The hook failed. - The hook was skipped. @@ -208,21 +208,21 @@ Use `/rpgkit.update_rpg` when: If the RPG seems significantly stale or corrupted, run a full encode instead: ```text -/rpgkit.encode +/cmind.encode ``` -## Updating an Existing RPG-Kit Project +## Updating an Existing CoderMind Project -Run `rpgkit update` from the project root to refresh scripts, command definitions, MCP configuration, gitignore rules, and hooks. +Run `cmind update` from the project root to refresh scripts, command definitions, MCP configuration, gitignore rules, and hooks. ```bash -rpgkit update -rpgkit update --ai claude -rpgkit update --no-upgrade -rpgkit update --no-mcp +cmind update +cmind update --ai claude +cmind update --no-upgrade +cmind update --no-mcp ``` -`rpgkit update` auto-detects the existing assistant configuration when possible. +`cmind update` auto-detects the existing assistant configuration when possible. ## Troubleshooting @@ -231,22 +231,22 @@ rpgkit update --no-mcp Run: ```bash -rpgkit check +cmind check ``` Install and authenticate the missing assistant CLI, or rerun init with the assistant you want: ```bash -rpgkit init my-project --ai claude -rpgkit init my-project --ai copilot +cmind init my-project --ai claude +cmind init my-project --ai copilot ``` ### MCP tools say `rpg_unavailable` -The MCP server is configured, but `.rpgkit/data/rpg.json` has not been created yet. Run: +The MCP server is configured, but `.cmind/data/rpg.json` has not been created yet. Run: ```text -/rpgkit.encode +/cmind.encode ``` ### Incremental update failed @@ -254,27 +254,27 @@ The MCP server is configured, but `.rpgkit/data/rpg.json` has not been created y Check: ```bash -tail -n 200 .rpgkit/logs/update_rpg.log +tail -n 200 .cmind/logs/update_rpg.log ``` Then run: ```text -/rpgkit.update_rpg +/cmind.update_rpg ``` -If the graph is corrupted or too stale, run `/rpgkit.encode` for a full rebuild. +If the graph is corrupted or too stale, run `/cmind.encode` for a full rebuild. ### Template download hits rate limits or private repo access errors -As of v0.1.4 `rpgkit init` and `rpgkit update` no longer fetch templates +As of v0.1.4 `cmind init` and `cmind update` no longer fetch templates from GitHub releases — templates are bundled inside the installed -`rpgkit-cli` wheel, so this class of error should no longer occur during +`cmind-cli` wheel, so this class of error should no longer occur during provisioning. To pick up newer templates, upgrade the CLI itself: ```bash -uv tool upgrade rpgkit-cli +uv tool upgrade cmind-cli ``` -`rpgkit update` does this automatically by default; pass `--no-upgrade` +`cmind update` does this automatically by default; pass `--no-upgrade` to opt out. diff --git a/CoderMind/docs/project-structure.md b/CoderMind/docs/project-structure.md index 5685770..c99e7e6 100644 --- a/CoderMind/docs/project-structure.md +++ b/CoderMind/docs/project-structure.md @@ -2,51 +2,51 @@ ## Workspace == Repo -RPG-Kit installs alongside your project code: the directory you run `rpgkit init` in, also called the workspace root, **is** the project repository root. There is no separate `repo/` subdirectory. This means: +CoderMind installs alongside your project code: the directory you run `cmind init` in, also called the workspace root, **is** the project repository root. There is no separate `repo/` subdirectory. This means: -- `rpgkit init my-project` creates `my-project/` containing both your source code (`src/`, `tests/`, `docs/`) and RPG-Kit's in-workspace configuration files (`.rpgkit/config.toml`, `.claude/`, `.github/`, `.vscode/`, depending on the selected agent). -- `rpgkit init --here` inside an existing git repository adds RPG-Kit on top of the existing code without moving the repository. -- A single `.git` repository tracks user-owned code and any RPG-Kit files the user chooses to commit. **Runtime data, logs, and the inner-git snapshot repo all live outside the workspace** under `~/.rpgkit/workspaces//`, so generated artefacts don't pollute your repo or accidentally get committed. Only a small set of user-facing files (`.rpgkit/config.toml`, `.rpgkit/reports/*.html`) stay inside the workspace. +- `cmind init my-project` creates `my-project/` containing both your source code (`src/`, `tests/`, `docs/`) and CoderMind's in-workspace configuration files (`.cmind/config.toml`, `.claude/`, `.github/`, `.vscode/`, depending on the selected agent). +- `cmind init --here` inside an existing git repository adds CoderMind on top of the existing code without moving the repository. +- A single `.git` repository tracks user-owned code and any CoderMind files the user chooses to commit. **Runtime data, logs, and the inner-git snapshot repo all live outside the workspace** under `~/.cmind/workspaces//`, so generated artefacts don't pollute your repo or accidentally get committed. Only a small set of user-facing files (`.cmind/config.toml`, `.cmind/reports/*.html`) stay inside the workspace. -## After `rpgkit init` +## After `cmind init` -Running `rpgkit init` downloads a template and creates a structure like this: +Running `cmind init` downloads a template and creates a structure like this: ```text my-project/ -├── docs/ # Optional requirement docs for /rpgkit.feature_spec +├── docs/ # Optional requirement docs for /cmind.feature_spec │ ├── project_charter.md # Auto-detected when no description is provided │ └── ... ├── .claude/ # Claude Code configuration when --ai claude -│ ├── commands/ # /rpgkit.* command definitions -│ │ ├── rpgkit.feature_spec.md -│ │ ├── rpgkit.feature_build.md -│ │ ├── rpgkit.feature_refactor.md -│ │ ├── rpgkit.feature_edit.md -│ │ ├── rpgkit.build_skeleton.md -│ │ ├── rpgkit.build_data_flow.md -│ │ ├── rpgkit.design_base_classes.md -│ │ ├── rpgkit.design_interfaces.md -│ │ ├── rpgkit.plan_tasks.md -│ │ ├── rpgkit.code_gen.md -│ │ ├── rpgkit.rpg_edit.md -│ │ ├── rpgkit.encode.md -│ │ └── rpgkit.update_rpg.md +│ ├── commands/ # /cmind.* command definitions +│ │ ├── cmind.feature_spec.md +│ │ ├── cmind.feature_build.md +│ │ ├── cmind.feature_refactor.md +│ │ ├── cmind.feature_edit.md +│ │ ├── cmind.build_skeleton.md +│ │ ├── cmind.build_data_flow.md +│ │ ├── cmind.design_base_classes.md +│ │ ├── cmind.design_interfaces.md +│ │ ├── cmind.plan_tasks.md +│ │ ├── cmind.code_gen.md +│ │ ├── cmind.rpg_edit.md +│ │ ├── cmind.encode.md +│ │ └── cmind.update_rpg.md │ └── settings.json # Permissions and MCP auto-approval ├── .github/ # Copilot configuration when --ai copilot -│ ├── agents/ # rpgkit.* agent definitions +│ ├── agents/ # cmind.* agent definitions │ └── prompts/ # companion prompts ├── .vscode/ # Copilot/VS Code configuration when applicable │ ├── mcp.json # MCP server registration │ └── tasks.json # Optional workspace tasks -└── .rpgkit/ +└── .cmind/ │ ├── config.toml # Workspace AI / config (committed). See docs/configuration.md │ ├── .source # Provisioning channel marker: "bundle" or "legacy" │ └── reports/ # User-facing HTML reports (rpg.html, review HTML, ...) └── .git/ # Your existing git repo - └── hooks/ # Installed by `rpgkit init` - ├── post-commit # Single line: `rpgkit hook post-commit` - └── post-merge # Single line: `rpgkit hook post-merge` + └── hooks/ # Installed by `cmind init` + ├── post-commit # Single line: `cmind hook post-commit` + └── post-merge # Single line: `cmind hook post-merge` ``` ### Out-of-workspace runtime store @@ -54,7 +54,7 @@ my-project/ Starting from the global-install layout, all runtime state lives under your home directory, keyed by a path-derived **slug** (the workspace's absolute path, lowercased, with non-alphanumeric runs collapsed to `-`): ```text -~/.rpgkit/workspaces// +~/.cmind/workspaces// ├── .git/ # Inner-git snapshot repo (per-stage auto-commits) ├── .gitignore # Excludes logs/copilot/ only — other logs are tracked for debug ├── .meta.toml # Back-pointer to the workspace path + metadata @@ -62,36 +62,36 @@ Starting from the global-install layout, all runtime state lives under your home └── logs/ # Per-stage logs (tracked by inner-git; LLM session traces under logs/copilot/ are excluded) ``` -Reports (`rpg.html`, review HTML, …) stay **inside** the workspace at `/.rpgkit/reports/` because they are small, user-facing artefacts that benefit from sitting next to the code (and may be committed). +Reports (`rpg.html`, review HTML, …) stay **inside** the workspace at `/.cmind/reports/` because they are small, user-facing artefacts that benefit from sitting next to the code (and may be committed). -`` is normally the slug itself (e.g. `home-hys-projects-myrepo`); paths whose slug exceeds 200 characters are truncated and given a 6-char base36 SHA-256 suffix so the directory name fits comfortably under POSIX `NAME_MAX` (255). Same shape as Claude Code's `~/.claude/projects/`. Moving or renaming the workspace yields a different id, so each clone has independent state. Run `rpgkit version` from inside the workspace to see the resolved paths (the **Data**, **Logs**, and **Inner git** lines). For backward compatibility, workspaces created before 0.1.4 (which used a 12-hex-char SHA-256 hash directory) continue to resolve correctly. +`` is normally the slug itself (e.g. `home-hys-projects-myrepo`); paths whose slug exceeds 200 characters are truncated and given a 6-char base36 SHA-256 suffix so the directory name fits comfortably under POSIX `NAME_MAX` (255). Same shape as Claude Code's `~/.claude/projects/`. Moving or renaming the workspace yields a different id, so each clone has independent state. Run `cmind version` from inside the workspace to see the resolved paths (the **Data**, **Logs**, and **Inner git** lines). For backward compatibility, workspaces created before 0.1.4 (which used a 12-hex-char SHA-256 hash directory) continue to resolve correctly. -> Pipeline scripts (formerly materialised into `.rpgkit/scripts/`) now live inside the installed `rpgkit-cli` wheel under `rpgkit_cli/core_pack/scripts/` and are invoked via the global [`rpgkit script `](cli-reference.md) command. They are no longer copied into each workspace, so `rpgkit init` produces a much smaller footprint and a single source of truth per CLI install. +> Pipeline scripts (formerly materialised into `.cmind/scripts/`) now live inside the installed `cmind-cli` wheel under `cmind_cli/core_pack/scripts/` and are invoked via the global [`cmind script `](cli-reference.md) command. They are no longer copied into each workspace, so `cmind init` produces a much smaller footprint and a single source of truth per CLI install. The agent configuration directory varies by the selected AI assistant and release package. For the verified CLI path, `--ai claude` installs `.claude/commands/`, while `--ai copilot` installs `.github/agents/`, `.github/prompts/`, and `.vscode/mcp.json`. -Command definitions are installed into the AI-agent-specific folder. Normal users should not need to inspect `~/.rpgkit/workspaces//data/` directly—run `rpgkit version` from the workspace to see all relevant paths. +Command definitions are installed into the AI-agent-specific folder. Normal users should not need to inspect `~/.cmind/workspaces//data/` directly—run `cmind version` from the workspace to see all relevant paths. ### Quick reference: where does each file live? | Artefact | Location | |---|---| | Your source code | `/` | -| Workspace AI config | `/.rpgkit/config.toml` | -| User-facing HTML reports (`rpg.html`, …) | `/.rpgkit/reports/` | +| Workspace AI config | `/.cmind/config.toml` | +| User-facing HTML reports (`rpg.html`, …) | `/.cmind/reports/` | | Agent command definitions | `/.claude/` or `/.github/` | | MCP / VS Code config | `/.vscode/` | | Git hooks (`post-commit`, `post-merge`) | `/.git/hooks/` | -| Generated data (`rpg.json`, `dep_graph.json`, …) | `~/.rpgkit/workspaces//data/` | -| Per-stage logs | `~/.rpgkit/workspaces//logs/` | -| Inner-git snapshot repo | `~/.rpgkit/workspaces//.git/` | -| Pipeline scripts (read-only) | inside the installed `rpgkit-cli` wheel | +| Generated data (`rpg.json`, `dep_graph.json`, …) | `~/.cmind/workspaces//data/` | +| Per-stage logs | `~/.cmind/workspaces//logs/` | +| Inner-git snapshot repo | `~/.cmind/workspaces//.git/` | +| Pipeline scripts (read-only) | inside the installed `cmind-cli` wheel | -To see the resolved paths for the current workspace, run `rpgkit version` from anywhere inside it. +To see the resolved paths for the current workspace, run `cmind version` from anywhere inside it. ## Generated Data Files -As you run `/rpgkit.*` commands, `~/.rpgkit/workspaces//data/` is progressively populated (paths below are shown relative to that directory): +As you run `/cmind.*` commands, `~/.cmind/workspaces//data/` is progressively populated (paths below are shown relative to that directory): | Generated file | Command | Description | | -------------- | ------- | ----------- | @@ -116,12 +116,12 @@ As you run `/rpgkit.*` commands, `~/.rpgkit/workspaces//data/` is ## `rpg.json` — The Repository Planning Graph -`rpg.json` is the central graph artifact used by the forward pipeline, reverse encoder, MCP tools, incremental update hooks, and `/rpgkit.rpg_edit`. +`rpg.json` is the central graph artifact used by the forward pipeline, reverse encoder, MCP tools, incremental update hooks, and `/cmind.rpg_edit`. It can be created in either direction: -1. **Forward pipeline:** `/rpgkit.build_skeleton` creates `rpg.json` from `feature_tree.json`. -2. **Reverse encoder:** `/rpgkit.encode` creates `rpg.json` from an existing codebase. +1. **Forward pipeline:** `/cmind.build_skeleton` creates `rpg.json` from `feature_tree.json`. +2. **Reverse encoder:** `/cmind.encode` creates `rpg.json` from an existing codebase. Later commands enrich or maintain the same file: @@ -134,23 +134,23 @@ Later commands enrich or maintain the same file: ## `dep_graph.json` — Code Dependency Graph -`dep_graph.json` stores the code-level dependency graph used by the encoder, incremental update path, and surgical edit path. It is maintained alongside `rpg.json` so RPG-Kit can keep feature-level structure and code-level dependencies aligned. +`dep_graph.json` stores the code-level dependency graph used by the encoder, incremental update path, and surgical edit path. It is maintained alongside `rpg.json` so CoderMind can keep feature-level structure and code-level dependencies aligned. Typical producers and updaters: -- `/rpgkit.encode` creates the initial dependency graph when encoding an existing codebase. -- The post-commit hook and `/rpgkit.update_rpg` refresh it after code changes. -- `/rpgkit.rpg_edit` refreshes it after applying targeted code edits. +- `/cmind.encode` creates the initial dependency graph when encoding an existing codebase. +- The post-commit hook and `/cmind.update_rpg` refresh it after code changes. +- `/cmind.rpg_edit` refreshes it after applying targeted code edits. ## Runtime Logs and Reports -Runtime logs are written under `~/.rpgkit/workspaces//logs/`, for example: +Runtime logs are written under `~/.cmind/workspaces//logs/`, for example: -- `~/.rpgkit/workspaces//logs/encode.log` -- `~/.rpgkit/workspaces//logs/update_rpg.log` -- `~/.rpgkit/workspaces//logs/feature_build.log` -- `~/.rpgkit/workspaces//logs/build_data_flow.log` +- `~/.cmind/workspaces//logs/encode.log` +- `~/.cmind/workspaces//logs/update_rpg.log` +- `~/.cmind/workspaces//logs/feature_build.log` +- `~/.cmind/workspaces//logs/build_data_flow.log` -Execution traces are written under `~/.rpgkit/workspaces//data/trajectory/`. Review or diagnostic artifacts may be written under `/.rpgkit/reports/` when a command generates them. +Execution traces are written under `~/.cmind/workspaces//data/trajectory/`. Review or diagnostic artifacts may be written under `/.cmind/reports/` when a command generates them. -To discover the home-side paths (data / logs / inner-git) for the current workspace, run `rpgkit version` from anywhere inside it—the relevant lines are labelled **Workspace**, **Data**, **Logs**, and **Inner git**. +To discover the home-side paths (data / logs / inner-git) for the current workspace, run `cmind version` from anywhere inside it—the relevant lines are labelled **Workspace**, **Data**, **Logs**, and **Inner git**. diff --git a/CoderMind/pyproject.toml b/CoderMind/pyproject.toml index fc5238b..a46b0e9 100644 --- a/CoderMind/pyproject.toml +++ b/CoderMind/pyproject.toml @@ -1,7 +1,7 @@ [project] -name = "rpgkit-cli" +name = "cmind-cli" version = "0.1.3" -description = "RPG-Kit CLI - A tool to generate feature trees for repository planning and code generation." +description = "CoderMind CLI - A tool to generate feature trees for repository planning and code generation." requires-python = ">=3.12" dependencies = [ "typer", @@ -28,8 +28,8 @@ dependencies = [ ] [project.scripts] -rpgkit = "rpgkit_cli:main" -rpgkit-mcp = "rpgkit_cli.entries:mcp_main" +cmind = "cmind_cli:main" +cmind-mcp = "cmind_cli.entries:mcp_main" [project.urls] Repository = "https://github.com/microsoft/RPG-ZeroRepo" @@ -39,13 +39,13 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] -packages = ["src/rpgkit_cli"] +packages = ["src/cmind_cli"] # Bundle core assets (scripts + slash-command templates) into the wheel under -# `rpgkit_cli/core_pack/` so that `rpgkit init` works offline (air-gapped / +# `cmind_cli/core_pack/` so that `cmind init` works offline (air-gapped / # corporate-proxy / enterprise environments). These are the SAME source files # the GitHub Release zip workflow packages; bundling them in the wheel just # gives users a network-free fast path. Plan: plans/01-package-bundle-and-ai-config.md [tool.hatch.build.targets.wheel.force-include] -"scripts" = "rpgkit_cli/core_pack/scripts" -"templates/commands" = "rpgkit_cli/core_pack/commands" +"scripts" = "cmind_cli/core_pack/scripts" +"templates/commands" = "cmind_cli/core_pack/commands" diff --git a/CoderMind/scripts/__init__.py b/CoderMind/scripts/__init__.py index 1c7afd0..abbb766 100644 --- a/CoderMind/scripts/__init__.py +++ b/CoderMind/scripts/__init__.py @@ -8,10 +8,10 @@ # require Python-package semantics. Keeping this empty marker file # avoids surprising build differences across hatch releases. # -# At runtime ``scripts/`` is NOT imported as ``rpgkit_cli.scripts`` +# At runtime ``scripts/`` is NOT imported as ``cmind_cli.scripts`` # — the wheel's ``force-include`` rewrites the install target to -# ``rpgkit_cli/core_pack/scripts/``, and that path is also not imported +# ``cmind_cli/core_pack/scripts/``, and that path is also not imported # as a Python module. Scripts are executed directly from the packaged -# location via the ``rpgkit script `` dispatcher, which resolves -# them through ``rpgkit_cli._assets.scripts_dir()``. +# location via the ``cmind script `` dispatcher, which resolves +# them through ``cmind_cli._assets.scripts_dir()``. # diff --git a/CoderMind/scripts/build_data_flow.py b/CoderMind/scripts/build_data_flow.py index 1c4fd6b..7d141c8 100644 --- a/CoderMind/scripts/build_data_flow.py +++ b/CoderMind/scripts/build_data_flow.py @@ -8,9 +8,9 @@ - Generates subtree processing order for later steps - Adds data flow dependencies as edges to repo_rpg.json -Input: .rpgkit/skeleton.json (file structure with component info) -Output: .rpgkit/data_flow.json (data flow edges and subtree order) - .rpgkit/repo_rpg.json (updated with data flow edges) +Input: .cmind/skeleton.json (file structure with component info) +Output: .cmind/data_flow.json (data flow edges and subtree order) + .cmind/repo_rpg.json (updated with data flow edges) """ import json @@ -314,7 +314,7 @@ def main(): if not input_path.exists(): logger.error(f"Input file not found: {input_path}") print(f"ERROR: Input file not found: {input_path}") - print("Please run /rpgkit.build_skeleton first.") + print("Please run /cmind.build_skeleton first.") return 1 with open(input_path, "r", encoding="utf-8") as f: diff --git a/CoderMind/scripts/build_skeleton.py b/CoderMind/scripts/build_skeleton.py index 30df76c..0c2cc0c 100644 --- a/CoderMind/scripts/build_skeleton.py +++ b/CoderMind/scripts/build_skeleton.py @@ -6,9 +6,9 @@ - Step 2: Generate directory structure mapping components to directories - Step 3: Assign features to specific Python files using professional prompts -Input: .rpgkit/feature_tree.json (component list from refactor step) -Output: .rpgkit/skeleton.json (tree-structured file skeleton with feature assignments) - .rpgkit/repo_rpg.json (intermediate RPG structure) +Input: .cmind/feature_tree.json (component list from refactor step) +Output: .cmind/skeleton.json (tree-structured file skeleton with feature assignments) + .cmind/repo_rpg.json (intermediate RPG structure) """ import json @@ -42,14 +42,14 @@ # Utility Functions # ============================================================================ -def convert_skeleton_to_rpgkit_format(skeleton: RepoSkeleton, rpg: RPG) -> Dict[str, Any]: - """Convert skeleton format to RPG-Kit's expected format. +def convert_skeleton_to_cmind_format(skeleton: RepoSkeleton, rpg: RPG) -> Dict[str, Any]: + """Convert skeleton format to CoderMind's expected format. This ensures compatibility with existing validation and summary scripts. """ def convert_node(node): - """Convert skeleton node to RPG-Kit format recursively.""" + """Convert skeleton node to CoderMind format recursively.""" result = { "type": "directory" if node.is_dir else "file", "name": node.name, @@ -70,7 +70,7 @@ def convert_node(node): return result - # Build RPG-Kit compatible output + # Build CoderMind compatible output output = { "repository_name": rpg.repo_name, "repository_purpose": rpg.repo_info, @@ -195,7 +195,7 @@ def build(self, input_data: Dict[str, Any]) -> Dict[str, Any]: print(f" [OK] Updated {paths_updated} nodes with path information") # Step 3: Convert and save results - print("\n[Step 3] Converting to RPG-Kit format...") + print("\n[Step 3] Converting to CoderMind format...") result = self._build_result() # Save updated RPG (with directory assignments) @@ -278,9 +278,9 @@ def _step2_file_design(self) -> bool: return False def _build_result(self) -> Dict[str, Any]: - """Build the final result dictionary in RPG-Kit format.""" - # Convert to RPG-Kit compatible format - result = convert_skeleton_to_rpgkit_format(self.skeleton, self.rpg) + """Build the final result dictionary in CoderMind format.""" + # Convert to CoderMind compatible format + result = convert_skeleton_to_cmind_format(self.skeleton, self.rpg) # Add statistics result["statistics"].update({ @@ -535,7 +535,7 @@ def patch_missing(input_data: Dict[str, Any]) -> Dict[str, Any]: node.meta.path = feature_to_file[fp] # Re-convert and save - result = convert_skeleton_to_rpgkit_format(skeleton, rpg) + result = convert_skeleton_to_cmind_format(skeleton, rpg) result["statistics"].update({ "rpg_nodes": len(rpg.nodes), "rpg_edges": len(rpg.edges), @@ -624,7 +624,7 @@ def main(): if not input_path.exists(): logger.error(f"Input file not found: {input_path}") print(f"ERROR: Input file not found: {input_path}") - print("Please run /rpgkit.refactor_feature first.") + print("Please run /cmind.refactor_feature first.") return 1 try: diff --git a/CoderMind/scripts/check_base_classes.py b/CoderMind/scripts/check_base_classes.py index f04e6b1..b9a0909 100644 --- a/CoderMind/scripts/check_base_classes.py +++ b/CoderMind/scripts/check_base_classes.py @@ -7,7 +7,7 @@ - Validates Python code syntax (error state if syntax errors) - Returns update state if valid -Input: .rpgkit/base_classes.json +Input: .cmind/base_classes.json """ import json diff --git a/CoderMind/scripts/check_code_gen.py b/CoderMind/scripts/check_code_gen.py index 66bbee0..16d3df6 100644 --- a/CoderMind/scripts/check_code_gen.py +++ b/CoderMind/scripts/check_code_gen.py @@ -133,7 +133,7 @@ def determine_state( if not valid: result["type"] = "error" result["message"] = "; ".join(errors) - result["next_action"] = "Fix the reported issues. If tasks.json is missing, run /rpgkit.plan_tasks first." + result["next_action"] = "Fix the reported issues. If tasks.json is missing, run /cmind.plan_tasks first." return result # Get all task IDs @@ -443,13 +443,13 @@ def print_status(result: Dict[str, Any], json_output: bool = False) -> None: if state_type == "error": print(" Fix the errors above before proceeding.") - print(" Run /rpgkit.plan_tasks to generate tasks.json") + print(" Run /cmind.plan_tasks to generate tasks.json") elif state_type == "init": - print(" Run /rpgkit.code_gen to start code generation") + print(" Run /cmind.code_gen to start code generation") elif state_type == "in_progress": - print(" Run /rpgkit.code_gen to continue current batch") + print(" Run /cmind.code_gen to continue current batch") elif state_type == "continue": - print(" Run /rpgkit.code_gen to process next batch") + print(" Run /cmind.code_gen to process next batch") elif state_type == "complete": print(" All done! Review the generated code.") diff --git a/CoderMind/scripts/check_data_flow.py b/CoderMind/scripts/check_data_flow.py index 84455dd..12b5004 100644 --- a/CoderMind/scripts/check_data_flow.py +++ b/CoderMind/scripts/check_data_flow.py @@ -7,8 +7,8 @@ - Cross-validates components between skeleton and data flow (warning state) - Returns update state if valid -Input: .rpgkit/data_flow.json -Reference: .rpgkit/skeleton.json +Input: .cmind/data_flow.json +Reference: .cmind/skeleton.json """ import json diff --git a/CoderMind/scripts/check_interfaces.py b/CoderMind/scripts/check_interfaces.py index d7cd326..299f51f 100644 --- a/CoderMind/scripts/check_interfaces.py +++ b/CoderMind/scripts/check_interfaces.py @@ -320,7 +320,7 @@ def check_state(input_path: Path, output_path: Path) -> Dict[str, Any]: # Check input (skeleton.json) if not result["input_exists"]: result["type"] = "error" - result["message"] = f"Input file not found: {input_path}. Please run /rpgkit.build_skeleton first." + result["message"] = f"Input file not found: {input_path}. Please run /cmind.build_skeleton first." return result input_valid, input_errors = validate_skeleton(input_path) diff --git a/CoderMind/scripts/check_skeleton.py b/CoderMind/scripts/check_skeleton.py index 8c2c692..59532eb 100644 --- a/CoderMind/scripts/check_skeleton.py +++ b/CoderMind/scripts/check_skeleton.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Check Skeleton Script. -Inspect .rpgkit/skeleton.json and validate its structure. +Inspect .cmind/skeleton.json and validate its structure. Also cross-validate feature paths between refactor_feature.json and skeleton.json. Decision rules: @@ -325,7 +325,7 @@ def inspect_state() -> Dict[str, Any]: # Determine type and message if not input_valid: type_value = "error" - message = "Input file missing or invalid. Run /rpgkit.refactor_feature first." + message = "Input file missing or invalid. Run /cmind.refactor_feature first." elif not output_exists or not output_valid: type_value = "init" message = "Ready to build skeleton." @@ -357,9 +357,9 @@ def inspect_state() -> Dict[str, Any]: # Add next_action for clear guidance if type_value == "init": - result["next_action"] = "rpgkit script build_skeleton.py --max-iterations 10" + result["next_action"] = "cmind script build_skeleton.py --max-iterations 10" elif type_value == "warning": - result["next_action"] = "rpgkit script build_skeleton.py --patch" + result["next_action"] = "cmind script build_skeleton.py --patch" else: result["next_action"] = "Skeleton is consistent. Proceed to next step." diff --git a/CoderMind/scripts/check_tasks.py b/CoderMind/scripts/check_tasks.py index 8b89913..99ecb15 100644 --- a/CoderMind/scripts/check_tasks.py +++ b/CoderMind/scripts/check_tasks.py @@ -283,7 +283,7 @@ def check_state(input_path: Path, output_path: Path) -> Dict[str, Any]: # Check input (interfaces.json) if not result["input_exists"]: result["type"] = "error" - result["message"] = f"Input file not found: {input_path}. Please run /rpgkit.design_interfaces first." + result["message"] = f"Input file not found: {input_path}. Please run /cmind.design_interfaces first." return result input_valid, input_errors = validate_interfaces(input_path) diff --git a/CoderMind/scripts/code_gen/__init__.py b/CoderMind/scripts/code_gen/__init__.py index 3e22e4e..bbd0a58 100644 --- a/CoderMind/scripts/code_gen/__init__.py +++ b/CoderMind/scripts/code_gen/__init__.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Code generation utilities used by ``scripts/run_batch.py`` and friends. -This package groups the libraries that drive the ``/rpgkit.code_gen`` +This package groups the libraries that drive the ``/cmind.code_gen`` pipeline: * :mod:`scripts.code_gen.prompts` — prompt templates diff --git a/CoderMind/scripts/code_gen/batch_prompts.py b/CoderMind/scripts/code_gen/batch_prompts.py index b74a2c1..4a74fb2 100644 --- a/CoderMind/scripts/code_gen/batch_prompts.py +++ b/CoderMind/scripts/code_gen/batch_prompts.py @@ -207,8 +207,8 @@ - Run: `git add -A && git commit -m ""` [FAIL] You MUST NOT: -- Modify or read files under `.rpgkit/` -- Run any `rpgkit script ...` or `rpgkit-mcp` commands +- Modify or read files under `.cmind/` +- Run any `cmind script ...` or `cmind-mcp` commands - Run arbitrary shell commands beyond pytest/pip/git listed above - Install packages that are not genuinely needed by the source code - Delete files that are not part of your task @@ -310,8 +310,8 @@ [FAIL] You MUST NOT: - Modify existing source code or test files -- Modify or read files under `.rpgkit/` -- Run any `rpgkit script ...` or `rpgkit-mcp` commands +- Modify or read files under `.cmind/` +- Run any `cmind script ...` or `cmind-mcp` commands ## Task Details @@ -338,7 +338,7 @@ [FAIL] You MUST NOT: - Modify existing source code or test files -- Modify or read files under `.rpgkit/` +- Modify or read files under `.cmind/` ## Task Details diff --git a/CoderMind/scripts/code_gen/final_validation.py b/CoderMind/scripts/code_gen/final_validation.py index ffc889f..fccb202 100644 --- a/CoderMind/scripts/code_gen/final_validation.py +++ b/CoderMind/scripts/code_gen/final_validation.py @@ -10,7 +10,7 @@ check + stub detection); if the smoke test reports actionable findings, a repair sub-agent is dispatched and the full pytest is re-run. -The stage's outcome is persisted to ``.rpgkit/logs/codegen_final_test.json`` +The stage's outcome is persisted to ``.cmind/logs/codegen_final_test.json`` (and ``codegen_smoke_test.json``) via :mod:`scripts.code_gen.stage_io` so that the global-review stage can consume the results without re-running pytest. diff --git a/CoderMind/scripts/code_gen/global_review.py b/CoderMind/scripts/code_gen/global_review.py index e44a99f..4489cb7 100644 --- a/CoderMind/scripts/code_gen/global_review.py +++ b/CoderMind/scripts/code_gen/global_review.py @@ -194,8 +194,8 @@ `--file`. This guarantees the script is reusable in future review iterations: ```bash # Write the test script to the reusable scripts directory -mkdir -p .rpgkit/tmp/gui_test_scripts -cat > .rpgkit/tmp/gui_test_scripts/01_create_shape.py << 'PYEOF' +mkdir -p .cmind/tmp/gui_test_scripts +cat > .cmind/tmp/gui_test_scripts/01_create_shape.py << 'PYEOF' import time # Verify: selecting a tool and using it on the canvas gui.click(120, 45) # open dropdown menu @@ -207,7 +207,7 @@ gui.screenshot() # verify result PYEOF # Run it -python $GUI_TOOL run-script --file .rpgkit/tmp/gui_test_scripts/01_create_shape.py +python $GUI_TOOL run-script --file .cmind/tmp/gui_test_scripts/01_create_shape.py ``` This way the script file persists and can be replayed in the next iteration. @@ -286,7 +286,7 @@ - Stop any background project processes you started - Delete any test databases you created (e.g., test_review.db) - For GUI apps: run `gui.py close` then `gui.py stop-display` - - For GUI apps: your test scripts in `.rpgkit/tmp/gui_test_scripts/` + - For GUI apps: your test scripts in `.cmind/tmp/gui_test_scripts/` are already saved (you wrote them to files before running via `--file`). Do NOT delete them — future review iterations will replay them. 12. Output the **Review Checklist** you've been building. Use this exact format: @@ -479,11 +479,11 @@ ``` **Multi-step interactions** — always write to a file first, then run via -`--file`. Scripts saved under `.rpgkit/tmp/gui_test_scripts/` persist across +`--file`. Scripts saved under `.cmind/tmp/gui_test_scripts/` persist across review iterations so the next agent can replay them: ```bash -mkdir -p .rpgkit/tmp/gui_test_scripts -cat > .rpgkit/tmp/gui_test_scripts/02_form_fill.py << 'PYEOF' +mkdir -p .cmind/tmp/gui_test_scripts +cat > .cmind/tmp/gui_test_scripts/02_form_fill.py << 'PYEOF' import time # Verify: dropdown selection + form fill + submit wid = gui.find_window("My App") @@ -501,7 +501,7 @@ time.sleep(0.5) gui.screenshot() # verify result PYEOF -python $GUI_TOOL run-script --file .rpgkit/tmp/gui_test_scripts/02_form_fill.py +python $GUI_TOOL run-script --file .cmind/tmp/gui_test_scripts/02_form_fill.py ``` **Simple one-off scripts** (no need to persist): @@ -652,10 +652,10 @@ def _collect_children(children: list, depth: int = 1, max_depth: int = 3) -> Lis def _load_gui_script_reuse_context(repo_path: Path) -> str: """Load reusable GUI interaction scripts for review prompt context. - Scripts are stored under ``repo/.rpgkit/tmp/gui_test_scripts`` and are + Scripts are stored under ``repo/.cmind/tmp/gui_test_scripts`` and are intended to capture stable, previously-validated interaction flows. """ - scripts_dir = repo_path / ".rpgkit" / "tmp" / "gui_test_scripts" + scripts_dir = repo_path / ".cmind" / "tmp" / "gui_test_scripts" if not scripts_dir.is_dir(): return "(No reusable GUI scripts found yet)" @@ -1121,7 +1121,7 @@ def global_review( # Clean screenshots from previous iteration so size check is fresh try: - screenshots_dir = repo_path / ".rpgkit" / "tmp" / "screenshots" + screenshots_dir = repo_path / ".cmind" / "tmp" / "screenshots" if screenshots_dir.is_dir(): shutil.rmtree(screenshots_dir) except Exception: @@ -1251,7 +1251,7 @@ def global_review( # self-reported metrics (which may be missing or malformed). if review_passed: try: - screenshots_dir = repo_path / ".rpgkit" / "tmp" / "screenshots" + screenshots_dir = repo_path / ".cmind" / "tmp" / "screenshots" if screenshots_dir.is_dir(): png_files = list(screenshots_dir.glob("*.png")) if png_files: diff --git a/CoderMind/scripts/code_gen/rpg_updater.py b/CoderMind/scripts/code_gen/rpg_updater.py index e4e03b1..cad8475 100644 --- a/CoderMind/scripts/code_gen/rpg_updater.py +++ b/CoderMind/scripts/code_gen/rpg_updater.py @@ -726,7 +726,7 @@ def run_rpg_update( # filesystem path. The path is only used to populate ``source_file`` in # edge metadata, which feeds into edge ``description`` text injected into # LLM prompts. Absolute paths leak host-specific prefixes - # (e.g. /home/.../RPG-Kit-backup/...) and mislead agents. + # (e.g. /home/.../CoderMind-backup/...) and mislead agents. analyzer.analyze_file(Path(batch.file_path), code) analyzed_deps = analyzer.get_all_edges() diff --git a/CoderMind/scripts/code_gen/stage_io.py b/CoderMind/scripts/code_gen/stage_io.py index c0f9214..7dd25d3 100644 --- a/CoderMind/scripts/code_gen/stage_io.py +++ b/CoderMind/scripts/code_gen/stage_io.py @@ -3,7 +3,7 @@ Each pipeline stage (``final_test``, ``smoke_test``, ``global_review``) writes its outcome to a JSON sidecar under -``.rpgkit/logs/codegen_.json`` so: +``.cmind/logs/codegen_.json`` so: * ``global_review`` can load earlier stages' findings without re-running them. @@ -31,7 +31,7 @@ def stage_path(name: str): def save_stage_result(name: str, data: Dict[str, Any]) -> None: - """Save a stage result to ``.rpgkit/logs/codegen_.json``. + """Save a stage result to ``.cmind/logs/codegen_.json``. Each pipeline stage (final_test, smoke_test, global_review) saves its output independently. Global review loads all of them as context. diff --git a/CoderMind/scripts/code_gen/static_checks.py b/CoderMind/scripts/code_gen/static_checks.py index b02a909..3badf39 100644 --- a/CoderMind/scripts/code_gen/static_checks.py +++ b/CoderMind/scripts/code_gen/static_checks.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Static Completeness Checks for RPG-Kit Code Generation. +"""Static Completeness Checks for CoderMind Code Generation. Project-type-agnostic static checks run after a subtree completes. These detect unimplemented stubs and placeholder returns without LLM cost. diff --git a/CoderMind/scripts/code_gen/test_runner.py b/CoderMind/scripts/code_gen/test_runner.py index 4f28020..546863d 100644 --- a/CoderMind/scripts/code_gen/test_runner.py +++ b/CoderMind/scripts/code_gen/test_runner.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Test Runner Utilities for RPG-Kit Code Generation. +"""Test Runner Utilities for CoderMind Code Generation. Provides utilities for: - Finding test files related to source changes diff --git a/CoderMind/scripts/common/__init__.py b/CoderMind/scripts/common/__init__.py index 7d0be31..a36a48b 100644 --- a/CoderMind/scripts/common/__init__.py +++ b/CoderMind/scripts/common/__init__.py @@ -44,7 +44,7 @@ ) from .paths import ( - RPGKIT_DIR, + CMIND_DIR, SKELETON_FILE, DATA_FLOW_FILE, @@ -58,7 +58,7 @@ CODE_GEN_STATE_FILE, TRAJECTORY_DIR, SKELETON_SUMMARY_FILE, - ensure_rpgkit_dir, + ensure_cmind_dir, get_trajectory_file, ) @@ -156,7 +156,7 @@ "create_task_branch", "complete_task_branch", # Paths - "RPGKIT_DIR", + "CMIND_DIR", "SKELETON_FILE", "DATA_FLOW_FILE", @@ -170,7 +170,7 @@ "CODE_GEN_STATE_FILE", "TRAJECTORY_DIR", "SKELETON_SUMMARY_FILE", - "ensure_rpgkit_dir", + "ensure_cmind_dir", "get_trajectory_file", # Utils "print_unicode_table", diff --git a/CoderMind/scripts/common/execution_state.py b/CoderMind/scripts/common/execution_state.py index 85154e4..00ceb5d 100644 --- a/CoderMind/scripts/common/execution_state.py +++ b/CoderMind/scripts/common/execution_state.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Execution State Management for RPG-Kit Code Generation. +"""Execution State Management for CoderMind Code Generation. Manages the state of code generation execution, including: - Current batch being processed @@ -8,7 +8,7 @@ - Git commit tracking This module handles state persistence between command invocations, -which is essential since RPG-Kit uses multiple CLI sessions. +which is essential since CoderMind uses multiple CLI sessions. """ import json @@ -395,7 +395,7 @@ def _count_total_tasks_from_tasks_json(state_path: Path = STATE_FILE) -> int: ``plan_tasks`` runs. The tasks.json path is derived from ``state_path`` (assumed to live in - the same ``.rpgkit/data/`` directory) so callers passing a custom + the same ``.cmind/data/`` directory) so callers passing a custom state_path see the matching tasks.json instead of the workspace default. """ @@ -729,7 +729,7 @@ def get_or_create_code_gen_trajectory( Returns: Trajectory instance (loaded or newly created) """ - # Trajectory files live under .rpgkit/data/trajectory/ (workspace level), + # Trajectory files live under .cmind/data/trajectory/ (workspace level), # not inside repo/, so base_dir should be the workspace root. base_dir = base_dir or WORKSPACE_ROOT diff --git a/CoderMind/scripts/common/git_utils.py b/CoderMind/scripts/common/git_utils.py index 68f28f4..172b6b2 100644 --- a/CoderMind/scripts/common/git_utils.py +++ b/CoderMind/scripts/common/git_utils.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Git Utilities for RPG-Kit Code Generation. +"""Git Utilities for CoderMind Code Generation. Provides Git operations for branch management and version control during the code generation phase: @@ -35,7 +35,7 @@ class GitRunner: - Safe directory handling """ - # The canonical main branch name used by all RPG-Kit repos. + # The canonical main branch name used by all CoderMind repos. MAIN_BRANCH = "main" def __init__( @@ -431,7 +431,7 @@ def ensure_clean_workspace(self, message: str = "pre-init-codebase") -> bool: # status commands need: # 1. No exceptions on missing / shallow / non-git repos (silent failure # with ``None`` return so the caller falls back gracefully). -# 2. Sub-second timeouts (a slow git call must not stall ``rpgkit init``, +# 2. Sub-second timeouts (a slow git call must not stall ``cmind init``, # a pre-commit hook, or VS Code's folderOpen task). # 3. No mutation of the working tree, index, or any git state. # @@ -531,7 +531,7 @@ def read_head(repo_dir: str | Path) -> Optional[dict]: # "no changes" from "git not available" without consulting # ``read_head`` first — that's intentional, falling back to full # sync in either case is safe); -# * filters to ``.py`` files at the source — RPG-Kit doesn't currently +# * filters to ``.py`` files at the source — CoderMind doesn't currently # parse anything else. When that changes, lift the filter into the # caller. diff --git a/CoderMind/scripts/common/llm_api_client.py b/CoderMind/scripts/common/llm_api_client.py index e721fb2..c71f3b4 100644 --- a/CoderMind/scripts/common/llm_api_client.py +++ b/CoderMind/scripts/common/llm_api_client.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -"""API-Based LLM Client for RPG-Kit. +"""API-Based LLM Client for CoderMind. This module provides direct API access to LLM providers as an optional complement to the existing CLI-based LLM client in ``llm_client.py``. Ported from RPG-ZeroRepo (zerorepo/rpg_gen/base/llm_client/) with adaptations -for RPG-Kit's project structure and coding conventions. +for CoderMind's project structure and coding conventions. Key components: - LLMConfig: Model configuration for unified LLM access across providers diff --git a/CoderMind/scripts/common/llm_client.py b/CoderMind/scripts/common/llm_client.py index 6a875d8..e9fddd7 100644 --- a/CoderMind/scripts/common/llm_client.py +++ b/CoderMind/scripts/common/llm_client.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""LLM Client Module for RPG-Kit. +"""LLM Client Module for CoderMind. This module provides a common LLM client with trajectory recording support. All LLM calls (prompts and responses) are recorded in the trajectory when @@ -41,8 +41,8 @@ def _set_pdeathsig() -> None: # # Resolution priority: # P1. LLMClient(tool="...") constructor argument -# P2. RPGKIT_AI_CLI_CMD env var -# P3. /.rpgkit/config.toml [rpgkit].ai_cli_cmd +# P2. CMIND_AI_CLI_CMD env var +# P3. /.cmind/config.toml [cmind].ai_cli_cmd # P4. _BAKED_IN_VALUE (release-zip builds substitute it at packaging time; # bundle builds leave the placeholder unchanged) # @@ -72,18 +72,18 @@ def _load_ai_cli_cmd() -> str: """ # P2: env var (highest non-P1 priority — useful in tests and one-off # overrides without editing the workspace config). - env_val = _os.environ.get("RPGKIT_AI_CLI_CMD", "").strip() + env_val = _os.environ.get("CMIND_AI_CLI_CMD", "").strip() if env_val: return env_val # P3: workspace config.toml. try: workspace = _paths._find_workspace_root() - cfg_path = workspace / ".rpgkit" / "config.toml" + cfg_path = workspace / ".cmind" / "config.toml" if cfg_path.exists(): with open(cfg_path, "rb") as f: data = tomllib.load(f) - cfg_val = (data.get("rpgkit") or {}).get("ai_cli_cmd", "") + cfg_val = (data.get("cmind") or {}).get("ai_cli_cmd", "") if isinstance(cfg_val, str): cfg_val = cfg_val.strip() if cfg_val: @@ -202,7 +202,7 @@ class LLMClient: # Workspace root — sourced from common.paths so that symlink-based # dev workflows resolve correctly (see paths._find_workspace_root). - # Used for session trace storage (.rpgkit/logs//) and to + # Used for session trace storage (.cmind/logs//) and to # express captured-trace paths relative to the workspace. _INFERRED_PROJECT_DIR: Path = _WORKSPACE_ROOT @@ -333,8 +333,8 @@ def generate( if not self.tool or self.tool == _PLACEHOLDER_LITERAL: raise RuntimeError( "AI CLI command not configured. Run " - "`rpgkit init --ai ` in this workspace, or set the " - "RPGKIT_AI_CLI_CMD environment variable." + "`cmind init --ai ` in this workspace, or set the " + "CMIND_AI_CLI_CMD environment variable." ) # Create call record @@ -571,8 +571,8 @@ def generate_with_memory( if not self.tool or self.tool == _PLACEHOLDER_LITERAL: raise RuntimeError( "AI CLI command not configured. Run " - "`rpgkit init --ai ` in this workspace, or set the " - "RPGKIT_AI_CLI_CMD environment variable." + "`cmind init --ai ` in this workspace, or set the " + "CMIND_AI_CLI_CMD environment variable." ) prompt = self._flatten_memory(memory) diff --git a/CoderMind/scripts/common/llm_types.py b/CoderMind/scripts/common/llm_types.py index 7bfb9f4..b871f1d 100644 --- a/CoderMind/scripts/common/llm_types.py +++ b/CoderMind/scripts/common/llm_types.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -"""LLM Type Definitions for RPG-Kit. +"""LLM Type Definitions for CoderMind. This module provides unified data structures for LLM interactions, including messages, responses, token usage tracking, and conversational memory. Ported from RPG-ZeroRepo (zerorepo/rpg_gen/base/llm_client/) with adaptations -for RPG-Kit's project structure and coding conventions. +for CoderMind's project structure and coding conventions. Key components: - LLMMessage: Standard message format for LLM interactions diff --git a/CoderMind/scripts/common/logging_setup.py b/CoderMind/scripts/common/logging_setup.py index b931815..07fd942 100644 --- a/CoderMind/scripts/common/logging_setup.py +++ b/CoderMind/scripts/common/logging_setup.py @@ -1,8 +1,8 @@ -"""Centralized logging configuration for RPG-Kit scripts. +"""Centralized logging configuration for CoderMind scripts. All scripts that produce non-trivial work should call :func:`setup_file_logging` once in their ``main()`` so that logs are -captured to ``/.rpgkit/logs/.log`` for later inspection. +captured to ``/.cmind/logs/.log`` for later inspection. Design goals ------------ @@ -14,7 +14,7 @@ script's own decision; this helper only attaches a *file* handler. * **Symlink-safe** — the log directory comes from ``common.paths``, which already resolves the workspace root correctly when - ``.rpgkit/scripts`` is a symlink in dev workflows. + ``.cmind/scripts`` is a symlink in dev workflows. * **Non-blocking on read-only filesystems** — if ``LOGS_DIR`` cannot be created or written to (e.g. CI, container, sandbox), the helper logs one warning to stderr and returns ``None`` instead of raising; the @@ -27,7 +27,7 @@ from common.logging_setup import setup_file_logging def main(): - setup_file_logging("rpg_edit") # → .rpgkit/logs/rpg_edit.log + setup_file_logging("rpg_edit") # → .cmind/logs/rpg_edit.log # … rest of script … The single ``log_name`` argument is the file *stem*; the ``.log`` @@ -60,7 +60,7 @@ def setup_file_logging( datefmt: str = _DEFAULT_DATEFMT, logs_dir: Optional[Path] = None, ) -> Optional[Path]: - """Attach a file handler that writes script logs under ``.rpgkit/logs/``. + """Attach a file handler that writes script logs under ``.cmind/logs/``. The root logger is reconfigured (only its level, never its existing handlers) so the new file handler actually receives records at @@ -69,7 +69,7 @@ def setup_file_logging( Args: log_name: Stem for the log file (``"rpg_edit"`` → - ``.rpgkit/logs/rpg_edit.log``). + ``.cmind/logs/rpg_edit.log``). level: Minimum level the file handler captures. Defaults to ``DEBUG`` so verbose runs are inspectable after the fact. fmt: ``logging.Formatter`` format string. @@ -90,7 +90,7 @@ def setup_file_logging( target_dir.mkdir(parents=True, exist_ok=True) except OSError as exc: print( - f"[rpgkit logging_setup] could not create {target_dir}: {exc}; " + f"[cmind logging_setup] could not create {target_dir}: {exc}; " "file logging disabled (console logs unaffected).", file=sys.stderr, ) @@ -109,7 +109,7 @@ def setup_file_logging( file_handler = logging.FileHandler(log_path, mode="a", encoding="utf-8") except OSError as exc: print( - f"[rpgkit logging_setup] could not open {log_path}: {exc}; " + f"[cmind logging_setup] could not open {log_path}: {exc}; " "file logging disabled (console logs unaffected).", file=sys.stderr, ) diff --git a/CoderMind/scripts/common/paths.py b/CoderMind/scripts/common/paths.py index 1ea9e6a..f45c38b 100644 --- a/CoderMind/scripts/common/paths.py +++ b/CoderMind/scripts/common/paths.py @@ -1,19 +1,19 @@ #!/usr/bin/env python3 """Centralized Path Definitions. -This module contains all file path constants used across RPG-Kit scripts. +This module contains all file path constants used across CoderMind scripts. -Directory layout (``~/.rpgkit/`` home storage): +Directory layout (``~/.cmind/`` home storage): / ← user's source repo - ├── .rpgkit/ ← minimal marker tree (in workspace) + ├── .cmind/ ← minimal marker tree (in workspace) │ ├── config.toml ← team-shared AI config (committable) │ └── reports/ ← user-facing artefacts (rpg.html, …) ├── .claude/ or .vscode/ ← agent instructions ├── src/ tests/ … ← project code (user-owned) └── .git/ ← single git repo at the workspace root - ~/.rpgkit/ ← user-global storage + ~/.cmind/ ← user-global storage └── workspaces// ├── .meta.toml ← channel, timestamps, version ├── .git/ ← Plan-03 inner snapshot repo @@ -22,7 +22,7 @@ └── logs/ ← *.log, mcp_calls.jsonl, … Machine-local data (``data/``, ``logs/``, the inner snapshot ``.git/``) -lives under ``~/.rpgkit/workspaces//`` so it survives independently +lives under ``~/.cmind/workspaces//`` so it survives independently of the workspace, never gets accidentally committed, and stays scoped to one user. The workspace dir keeps only the lightweight, team-shared files that benefit from being version-controlled alongside the code. @@ -40,19 +40,19 @@ import os from pathlib import Path -# Import the home-storage helpers. rpgkit_cli is always installed in +# Import the home-storage helpers. cmind_cli is always installed in # the same Python environment as the scripts (the wheel ships the -# scripts under ``rpgkit_cli/core_pack/scripts/``), so the import is +# scripts under ``cmind_cli/core_pack/scripts/``), so the import is # robust to where the script gets invoked from. We keep a fallback # that mirrors the legacy in-workspace layout in case someone imports # this module from a standalone python install that doesn't have -# rpgkit_cli on sys.path — e.g. a third-party tool dropping in for +# cmind_cli on sys.path — e.g. a third-party tool dropping in for # inspection. try: - from rpgkit_cli import _storage as _rpgkit_storage # type: ignore[import-not-found] + from cmind_cli import _storage as _cmind_storage # type: ignore[import-not-found] _HOME_STORAGE_AVAILABLE = True except Exception: # pragma: no cover - defensive - _rpgkit_storage = None # type: ignore[assignment] + _cmind_storage = None # type: ignore[assignment] _HOME_STORAGE_AVAILABLE = False @@ -60,21 +60,21 @@ # Workspace Root (absolute) # ============================================================================ # -# WORKSPACE_ROOT is the directory that contains ``.rpgkit/``. Resolving it -# from ``__file__`` is unreliable in dev workflows where ``.rpgkit/scripts`` +# WORKSPACE_ROOT is the directory that contains ``.cmind/``. Resolving it +# from ``__file__`` is unreliable in dev workflows where ``.cmind/scripts`` # is a symlink to a shared code repo: Python 3.11+ realpath-normalizes the # script's ``__file__`` at launch, which silently strips the symlink and # makes ``WORKSPACE_ROOT`` point at the *code* repo instead of the user's # workspace — every ``DATA_DIR`` / ``REPO_DIR`` derivation then breaks. # # Strategy (in order): -# 1. Walk up from ``cwd`` looking for a ``.rpgkit/`` marker — works for -# all normal invocations (rpgkit slash-commands and git hooks launch +# 1. Walk up from ``cwd`` looking for a ``.cmind/`` marker — works for +# all normal invocations (cmind slash-commands and git hooks launch # with cwd at the workspace root). Authoritative when found, even -# if a stale ``RPGKIT_WORKSPACE`` env var inherited from a parent +# if a stale ``CMIND_WORKSPACE`` env var inherited from a parent # process points elsewhere. -# 2. ``RPGKIT_WORKSPACE`` env var — explicit override / fallback -# when cwd doesn't contain ``.rpgkit/`` (e.g. running CLI scripts +# 2. ``CMIND_WORKSPACE`` env var — explicit override / fallback +# when cwd doesn't contain ``.cmind/`` (e.g. running CLI scripts # from outside the workspace). # 3. ``__file__`` fallback — preserves the standard deployment # layout when neither of the above applies. @@ -84,33 +84,33 @@ def _find_workspace_root() -> Path: # they were launched against, not a stale value inherited from the # parent process's environment. This matters for git hooks, which # are spawned by ``git`` (cwd = repo root) from arbitrary parent - # contexts that may have set RPGKIT_WORKSPACE long ago. + # contexts that may have set CMIND_WORKSPACE long ago. # - # Use the ``.rpgkit/config.toml`` marker (the canonical workspace - # signal of "this is an rpgkit workspace"). Falling back to just - # ``.rpgkit/`` would still work for newly-init'd workspaces, but - # using ``config.toml`` matches :func:`rpgkit_cli._storage + # Use the ``.cmind/config.toml`` marker (the canonical workspace + # signal of "this is an cmind workspace"). Falling back to just + # ``.cmind/`` would still work for newly-init'd workspaces, but + # using ``config.toml`` matches :func:`cmind_cli._storage # .find_workspace_root_from` exactly so the MCP server and pipeline # scripts agree on the boundary. cwd = Path.cwd().absolute() for cand in [cwd, *cwd.parents]: - if (cand / ".rpgkit" / "config.toml").is_file(): + if (cand / ".cmind" / "config.toml").is_file(): return cand - # Belt-and-braces fallback: also accept a bare ``.rpgkit/`` + # Belt-and-braces fallback: also accept a bare ``.cmind/`` # directory. This lets a freshly-cloned workspace whose # ``config.toml`` was somehow missing still be discovered # rather than silently degrading to the env-var path below. - if (cand / ".rpgkit").is_dir(): + if (cand / ".cmind").is_dir(): return cand - env = os.environ.get("RPGKIT_WORKSPACE") + env = os.environ.get("CMIND_WORKSPACE") if env: p = Path(env).absolute() if p.is_dir(): return p # Last resort: standard deployment layout - # /.rpgkit/scripts/common/paths.py + # /.cmind/scripts/common/paths.py return Path(__file__).absolute().parent.parent.parent.parent @@ -138,8 +138,8 @@ def _find_workspace_root() -> Path: # Anchor SCRIPTS_DIR to ``__file__``'s parent so the constant resolves # correctly regardless of how the scripts were deployed. Scripts live # inside the installed wheel at -# ``/rpgkit_cli/core_pack/scripts/`` and are invoked via -# ``rpgkit script ``. +# ``/cmind_cli/core_pack/scripts/`` and are invoked via +# ``cmind script ``. # # The surrounding ``common/`` package is at # ``SCRIPTS_DIR/common/``, so ``Path(__file__).parent.parent`` is the @@ -148,7 +148,7 @@ def _find_workspace_root() -> Path: # # For *user-facing hints* embedded in ``next_action`` messages, prefer # :func:`cmd_for` instead of stringifying ``SCRIPTS_DIR`` — the former -# emits the supported ``rpgkit script `` invocation rather than a +# emits the supported ``cmind script `` invocation rather than a # raw filesystem path the user can't easily re-run. SCRIPTS_DIR = Path(__file__).resolve().parent.parent @@ -167,7 +167,7 @@ def get_scripts_dir() -> str: def cmd_for(script_relpath: str) -> str: - """Return the canonical ``rpgkit script`` invocation for a script. + """Return the canonical ``cmind script`` invocation for a script. Args: script_relpath: Path relative to the scripts root, e.g. @@ -175,43 +175,43 @@ def cmd_for(script_relpath: str) -> str: slashes are stripped; ``.py`` suffix is preserved. Returns: - A shell-ready string such as ``"rpgkit script run_batch.py"``. + A shell-ready string such as ``"cmind script run_batch.py"``. Use this for any ``next_action`` hint or error message that suggests the user run a script. The workspace no - longer hosts a ``.rpgkit/scripts/`` copy, so the historic - ``python3 .rpgkit/scripts/X.py`` form would fail; ``rpgkit script + longer hosts a ``.cmind/scripts/`` copy, so the historic + ``python3 .cmind/scripts/X.py`` form would fail; ``cmind script X.py`` works regardless of workspace layout. """ - return f"rpgkit script {script_relpath.lstrip('/')}" + return f"cmind script {script_relpath.lstrip('/')}" # ============================================================================ -# .rpgkit Directory Structure (runtime state in user home) +# .cmind Directory Structure (runtime state in user home) # ========================================================================== # # Layout: # -# RPGKIT_DIR = /.rpgkit/ (minimal marker tree: config.toml + .source) -# DATA_DIR = ~/.rpgkit/workspaces//data/ -# LOGS_DIR = ~/.rpgkit/workspaces//logs/ -# REPORTS_DIR = /.rpgkit/reports/ (kept in workspace by +# CMIND_DIR = /.cmind/ (minimal marker tree: config.toml + .source) +# DATA_DIR = ~/.cmind/workspaces//data/ +# LOGS_DIR = ~/.cmind/workspaces//logs/ +# REPORTS_DIR = /.cmind/reports/ (kept in workspace by # design: small, user-facing, may be git-tracked) # # Falling back to the legacy in-workspace paths when ``_storage`` is # unavailable keeps this module importable from third-party tools that -# don't ship rpgkit_cli in the same env. +# don't ship cmind_cli in the same env. -RPGKIT_DIR = WORKSPACE_ROOT / ".rpgkit" +CMIND_DIR = WORKSPACE_ROOT / ".cmind" -if _HOME_STORAGE_AVAILABLE and _rpgkit_storage is not None: - DATA_DIR = _rpgkit_storage.workspace_data_dir(WORKSPACE_ROOT) - LOGS_DIR = _rpgkit_storage.workspace_logs_dir(WORKSPACE_ROOT) - REPORTS_DIR = _rpgkit_storage.workspace_reports_dir(WORKSPACE_ROOT) +if _HOME_STORAGE_AVAILABLE and _cmind_storage is not None: + DATA_DIR = _cmind_storage.workspace_data_dir(WORKSPACE_ROOT) + LOGS_DIR = _cmind_storage.workspace_logs_dir(WORKSPACE_ROOT) + REPORTS_DIR = _cmind_storage.workspace_reports_dir(WORKSPACE_ROOT) else: - DATA_DIR = RPGKIT_DIR / "data" - LOGS_DIR = RPGKIT_DIR / "logs" - REPORTS_DIR = RPGKIT_DIR / "reports" + DATA_DIR = CMIND_DIR / "data" + LOGS_DIR = CMIND_DIR / "logs" + REPORTS_DIR = CMIND_DIR / "reports" COPILOT_LOGS_DIR = LOGS_DIR / "copilot" CLAUDE_LOGS_DIR = LOGS_DIR / "claude" @@ -269,9 +269,9 @@ def cmd_for(script_relpath: str) -> str: # rpg.html lives in REPORTS_DIR (workspace-side) rather than next to # rpg.json (home-side) because the HTML is a *user-facing* artefact - # something the developer opens in a browser and may want to share / -# commit alongside the source. Keeping it in ``.rpgkit/reports/`` also +# commit alongside the source. Keeping it in ``.cmind/reports/`` also # means double-clicking it from a file explorer "just works" without -# having to dig into ``~/.rpgkit/workspaces//``. +# having to dig into ``~/.cmind/workspaces//``. RPG_HTML_FILE = REPORTS_DIR / "rpg.html" @@ -316,18 +316,18 @@ def cmd_for(script_relpath: str) -> str: # Helper Functions # ============================================================================ -def ensure_rpgkit_dir() -> Path: +def ensure_cmind_dir() -> Path: """Ensure ``DATA_DIR`` exists and return its path. In the home-storage layout, ``DATA_DIR`` lives under - ``~/.rpgkit/workspaces//data/``. We only create the leaf + ``~/.cmind/workspaces//data/``. We only create the leaf directory here; full home-layout bootstrap (including - ``.meta.toml``) is the responsibility of ``rpgkit init`` / - ``rpgkit update``. Calling this from a script that lands in a + ``.meta.toml``) is the responsibility of ``cmind init`` / + ``cmind update``. Calling this from a script that lands in a workspace without a meta file is supported — the data dir still gets created and the script can write its output — but the workspace won't be properly registered until the user runs - ``rpgkit update`` (or ``init``). + ``cmind update`` (or ``init``). """ DATA_DIR.mkdir(parents=True, exist_ok=True) return DATA_DIR diff --git a/CoderMind/scripts/common/rpg_io.py b/CoderMind/scripts/common/rpg_io.py index 98899e1..990ffe4 100644 --- a/CoderMind/scripts/common/rpg_io.py +++ b/CoderMind/scripts/common/rpg_io.py @@ -12,7 +12,7 @@ 2. **Silent corruption with no recovery path** — once truncated, the only "fix" was to re-encode from scratch. But the inner-git snapshot repo already holds the previous good state at - ``~/.rpgkit/workspaces//.git/``; we just weren't using it. + ``~/.cmind/workspaces//.git/``; we just weren't using it. This module fixes both with two complementary primitives: @@ -149,21 +149,21 @@ def safe_load_rpg(path: Path | str) -> Any: # --------------------------------------------------------------------------- # Filenames inside the inner-git repo that we know how to recover. -# Mirrors the layout produced by :mod:`rpgkit_cli._inner_git`: +# Mirrors the layout produced by :mod:`cmind_cli._inner_git`: # ``data/rpg.json``, ``data/dep_graph.json``, etc. def _git_relpath_for(path: Path) -> Optional[str]: """Return the path relative to the home-workspace dir for git lookup. - ``rpg.json`` lives at ``~/.rpgkit/workspaces//data/rpg.json``; - the inner git repo is rooted at ``~/.rpgkit/workspaces//``, + ``rpg.json`` lives at ``~/.cmind/workspaces//data/rpg.json``; + the inner git repo is rooted at ``~/.cmind/workspaces//``, so the path we ``git checkout`` is ``data/rpg.json``. Falls back to ``None`` when ``path`` doesn't look like it lives under such a home dir (e.g. test fixtures passing absolute paths into ``/tmp``). """ parts = path.resolve().parts - # Look for ".rpgkit/workspaces//..." in the path's components. + # Look for ".cmind/workspaces//..." in the path's components. try: - idx = parts.index(".rpgkit") + idx = parts.index(".cmind") if ( idx + 2 < len(parts) and parts[idx + 1] == "workspaces" @@ -211,7 +211,7 @@ def _try_restore_from_inner_git( # Strip any inherited ``GIT_*`` vars (e.g. ``GIT_DIR``, # ``GIT_INDEX_FILE``) that would point ``git`` at the **outer** # repository when this recovery runs inside a hook context. This - # mirrors the env-sanitisation done in ``rpgkit_cli._inner_git._run_git``. + # mirrors the env-sanitisation done in ``cmind_cli._inner_git._run_git``. env = {k: v for k, v in os.environ.items() if k not in ("GIT_INDEX_FILE", "GIT_DIR", "GIT_WORK_TREE", "GIT_OBJECT_DIRECTORY")} @@ -259,7 +259,7 @@ def _try_restore_from_inner_git( logger.warning( "rpg-io: %s was corrupted (%s at line %d col %d); auto-restored " - "from inner-git snapshot %s. Run `rpgkit version` to see the " + "from inner-git snapshot %s. Run `cmind version` to see the " "exact inner-git path.", path, original_exc.msg, diff --git a/CoderMind/scripts/common/session_manager.py b/CoderMind/scripts/common/session_manager.py index 5a3f411..df8fd5a 100644 --- a/CoderMind/scripts/common/session_manager.py +++ b/CoderMind/scripts/common/session_manager.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Session Manager Module for RPG-Kit. +"""Session Manager Module for CoderMind. Provides a base class and CLI-specific subclasses for managing AI CLI sessions: injecting tool-specific CLI arguments, preparing prompt @@ -249,8 +249,8 @@ class ClaudeSessionManager(SessionManager): where ```` replaces ``/`` and ``_`` with ``-``. """ - # Captured traces live under ``.rpgkit/logs/claude/`` so all - # RPG-Kit-managed artefacts stay inside ``.rpgkit/`` (single ignore + # Captured traces live under ``.cmind/logs/claude/`` so all + # CoderMind-managed artefacts stay inside ``.cmind/`` (single ignore # rule, single cleanup target). ``CLAUDE_LOGS_DIR`` is an absolute # path anchored at the workspace root (see ``common.paths``); the # base :meth:`_dest_dir` detects this and uses it as-is rather than diff --git a/CoderMind/scripts/common/task_batch.py b/CoderMind/scripts/common/task_batch.py index 295396a..8c99c23 100644 --- a/CoderMind/scripts/common/task_batch.py +++ b/CoderMind/scripts/common/task_batch.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""PlannedTask Data Class for RPG-Kit. +"""PlannedTask Data Class for CoderMind. Represents a single planned implementation task. Each task contains one or more units from a single file to be diff --git a/CoderMind/scripts/common/tools.py b/CoderMind/scripts/common/tools.py index 7efc80c..a727321 100644 --- a/CoderMind/scripts/common/tools.py +++ b/CoderMind/scripts/common/tools.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -"""Tool Abstraction Layer for RPG-Kit. +"""Tool Abstraction Layer for CoderMind. This module provides a unified tool abstraction for the RPG Agent, enabling standardized tool definition, parameter validation, execution, and result handling. Ported from RPG-ZeroRepo (zerorepo/rpg_gen/base/tools/) with adaptations for -RPG-Kit's project structure and coding conventions. +CoderMind's project structure and coding conventions. Key components: - Tool (ABC): Abstract base class for all agent tools diff --git a/CoderMind/scripts/common/trajectory.py b/CoderMind/scripts/common/trajectory.py index 1a4ec76..032f5b2 100644 --- a/CoderMind/scripts/common/trajectory.py +++ b/CoderMind/scripts/common/trajectory.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Trajectory Recording Module for RPG-Kit. +"""Trajectory Recording Module for CoderMind. This module provides utilities for recording command execution trajectories, including: @@ -10,7 +10,7 @@ - Resume support for interrupted executions Each command (build_feature, refactor_feature, build_skeleton, etc.) -maintains its own trajectory file in .rpgkit/trajectory/ +maintains its own trajectory file in .cmind/trajectory/ """ import json diff --git a/CoderMind/scripts/design_base_classes.py b/CoderMind/scripts/design_base_classes.py index b6f6ad2..df75f5b 100644 --- a/CoderMind/scripts/design_base_classes.py +++ b/CoderMind/scripts/design_base_classes.py @@ -8,9 +8,9 @@ - Validates Python code syntax Input: - - .rpgkit/skeleton.json (file structure) - - .rpgkit/data_flow.json (data flow between components) -Output: .rpgkit/base_classes.json (base class definitions with code) + - .cmind/skeleton.json (file structure) + - .cmind/data_flow.json (data flow between components) +Output: .cmind/base_classes.json (base class definitions with code) """ import json @@ -466,7 +466,7 @@ def main(): if not skeleton_path.exists(): logger.error(f"Skeleton file not found: {skeleton_path}") print(f"ERROR: Skeleton file not found: {skeleton_path}") - print("Please run /rpgkit.build_skeleton first.") + print("Please run /cmind.build_skeleton first.") return 1 with open(skeleton_path, "r", encoding="utf-8") as f: @@ -484,7 +484,7 @@ def main(): else: logger.warning(f"Data flow file not found: {data_flow_path}") print(f"[WARNING] Warning: Data flow file not found: {data_flow_path}") - print(" Run /rpgkit.build_data_flow first for better results.") + print(" Run /cmind.build_data_flow first for better results.") # Initialize trajectory trajectory = None diff --git a/CoderMind/scripts/design_interfaces.py b/CoderMind/scripts/design_interfaces.py index a1b70bc..90a843c 100644 --- a/CoderMind/scripts/design_interfaces.py +++ b/CoderMind/scripts/design_interfaces.py @@ -10,12 +10,12 @@ - Updates repo_rpg.json with dependency edges Input: - - .rpgkit/skeleton.json (file structure with feature assignments) - - .rpgkit/data_flow.json (data flow with subtree order) - - .rpgkit/base_classes.json (base classes for context) + - .cmind/skeleton.json (file structure with feature assignments) + - .cmind/data_flow.json (data flow with subtree order) + - .cmind/base_classes.json (base classes for context) Output: - - .rpgkit/interfaces.json (interfaces organized by subtree and file, with enhanced_data_flow) - - .rpgkit/repo_rpg.json (updated with fine-grained dependency edges) + - .cmind/interfaces.json (interfaces organized by subtree and file, with enhanced_data_flow) + - .cmind/repo_rpg.json (updated with fine-grained dependency edges) """ import json @@ -1134,7 +1134,7 @@ def main(): if not skeleton_path.exists(): logger.error(f"Skeleton file not found: {skeleton_path}") print(f"ERROR: Skeleton file not found: {skeleton_path}") - print("Please run /rpgkit.build_skeleton first.") + print("Please run /cmind.build_skeleton first.") return 1 with open(skeleton_path, "r", encoding="utf-8") as f: @@ -1152,7 +1152,7 @@ def main(): else: logger.warning(f"Data flow file not found: {data_flow_path}") print(f"[WARNING] Warning: Data flow file not found: {data_flow_path}") - print(" Run /rpgkit.build_data_flow first for better results.") + print(" Run /cmind.build_data_flow first for better results.") # Load base classes base_classes_path = Path(args.base_classes) @@ -1166,7 +1166,7 @@ def main(): else: logger.warning(f"Base classes file not found: {base_classes_path}") print(f"[WARNING] Warning: Base classes file not found: {base_classes_path}") - print(" Run /rpgkit.design_base_classes first for better results.") + print(" Run /cmind.design_base_classes first for better results.") # Initialize trajectory trajectory = None diff --git a/CoderMind/scripts/feature/__init__.py b/CoderMind/scripts/feature/__init__.py index 462e4c4..d46d867 100644 --- a/CoderMind/scripts/feature/__init__.py +++ b/CoderMind/scripts/feature/__init__.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Feature Module for RPG-Kit. +"""Feature Module for CoderMind. This module provides prompt templates for feature tree operations: - Feature build (expansion and review) diff --git a/CoderMind/scripts/feature_build_validation.py b/CoderMind/scripts/feature_build_validation.py index 09e7259..d57d95c 100644 --- a/CoderMind/scripts/feature_build_validation.py +++ b/CoderMind/scripts/feature_build_validation.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 -"""Validate feature_spec.json (input) and feature_build.json (output) for /rpgkit.feature_build command. +"""Validate feature_spec.json (input) and feature_build.json (output) for /cmind.feature_build command. This script checks: -1. Input file: .rpgkit/data/feature_spec.json +1. Input file: .cmind/data/feature_spec.json - File existence - Required fields: meta, background_and_overview, functional_requirements - Fields must exist and not be empty -2. Output file: .rpgkit/data/feature_build.json +2. Output file: .cmind/data/feature_build.json - File existence - Fields status: repository_name, repository_purpose, repository_specification, feature_tree @@ -100,7 +100,7 @@ def count_nodes(nodes: List[Dict[str, Any]]) -> int: def validate_input_file() -> Dict[str, Any]: - """Validate the input file (.rpgkit/data/feature_spec.json).""" + """Validate the input file (.cmind/data/feature_spec.json).""" result = { "valid": False, "exists": False, @@ -186,7 +186,7 @@ def validate_input_file() -> Dict[str, Any]: def check_output_file() -> Dict[str, Any]: - """Check the output file (.rpgkit/data/feature_build.json) status.""" + """Check the output file (.cmind/data/feature_build.json) status.""" result = { "exists": False, "has_content": False, diff --git a/CoderMind/scripts/feature_edit.py b/CoderMind/scripts/feature_edit.py index 3ab93f5..305b0ad 100644 --- a/CoderMind/scripts/feature_edit.py +++ b/CoderMind/scripts/feature_edit.py @@ -5,7 +5,7 @@ Phase 2: Execution - Execute the plan precisely on each component Phase 3: Review - Verify changes and auto-fix if needed (up to 3 rounds) -Input/Output: .rpgkit/data/feature_tree.json +Input/Output: .cmind/data/feature_tree.json """ import json diff --git a/CoderMind/scripts/feature_edit_validation.py b/CoderMind/scripts/feature_edit_validation.py index df1d73c..cd62677 100644 --- a/CoderMind/scripts/feature_edit_validation.py +++ b/CoderMind/scripts/feature_edit_validation.py @@ -2,7 +2,7 @@ """Inspect feature tree state and decide execution state for feature_edit. Decision rules: -- Check if .rpgkit/data/feature_tree.json exists +- Check if .cmind/data/feature_tree.json exists - Check if 'components' field exists and is not empty (generated by feature_refactor) - Check if repository_name exists and is not empty - Accept edit_instruction parameter and save to feature_tree.json @@ -116,7 +116,7 @@ def inspect_state(edit_instruction: str = "") -> Dict[str, Any]: return { "type": "error", "error_code": "file_not_found", - "message": f"Input file '{FEATURE_TREE_FILE}' does not exist. Please run /rpgkit.feature_refactor first.", + "message": f"Input file '{FEATURE_TREE_FILE}' does not exist. Please run /cmind.feature_refactor first.", "file": str(FEATURE_TREE_FILE), } @@ -137,7 +137,7 @@ def inspect_state(edit_instruction: str = "") -> Dict[str, Any]: return { "type": "error", "error_code": "field_empty", - "message": f"Field 'components' is missing or empty in '{FEATURE_TREE_FILE}'. Please run /rpgkit.feature_refactor to generate components.", + "message": f"Field 'components' is missing or empty in '{FEATURE_TREE_FILE}'. Please run /cmind.feature_refactor to generate components.", "file": str(FEATURE_TREE_FILE), "missing_field": "components", } diff --git a/CoderMind/scripts/feature_refactor_validation.py b/CoderMind/scripts/feature_refactor_validation.py index 9aa47ec..59c132a 100644 --- a/CoderMind/scripts/feature_refactor_validation.py +++ b/CoderMind/scripts/feature_refactor_validation.py @@ -1,13 +1,13 @@ #!/usr/bin/env python3 -"""Validate feature_build.json (input) and feature_tree.json (output) for /rpgkit.feature_refactor command. +"""Validate feature_build.json (input) and feature_tree.json (output) for /cmind.feature_refactor command. This script checks: -1. Input file: .rpgkit/data/feature_build.json +1. Input file: .cmind/data/feature_build.json - File existence - Required fields: repository_name, repository_purpose, feature_tree - Fields must exist and not be empty -2. Output file: .rpgkit/data/feature_tree.json +2. Output file: .cmind/data/feature_tree.json - File existence - Fields status: repository_name, repository_purpose, feature_tree, components @@ -99,7 +99,7 @@ def count_feature_tree_leaves(tree: Dict[str, Any]) -> int: def validate_input_file() -> Dict[str, Any]: - """Validate the input file (.rpgkit/data/feature_build.json).""" + """Validate the input file (.cmind/data/feature_build.json).""" result = { "valid": False, "exists": False, @@ -146,7 +146,7 @@ def validate_input_file() -> Dict[str, Any]: def check_output_file() -> Dict[str, Any]: - """Check the output file (.rpgkit/data/feature_tree.json) status.""" + """Check the output file (.cmind/data/feature_tree.json) status.""" result = { "exists": False, "has_content": False, diff --git a/CoderMind/scripts/feature_spec_to_json.py b/CoderMind/scripts/feature_spec_to_json.py index a9ae48f..d6ec4e5 100644 --- a/CoderMind/scripts/feature_spec_to_json.py +++ b/CoderMind/scripts/feature_spec_to_json.py @@ -8,11 +8,11 @@ Output: A structured JSON file with all parsed content. Usage: - rpgkit script feature_spec_to_json.py [--input-dir DIR] [--output FILE] [--no-evidence] + cmind script feature_spec_to_json.py [--input-dir DIR] [--output FILE] [--no-evidence] Arguments: --input-dir Directory containing feature_spec.md and features/ folder - Default: .rpgkit/data/feature_spec + Default: .cmind/data/feature_spec --output Output JSON file path Default: feature_spec.json in input directory --no-evidence Exclude evidence fields from output for compact JSON @@ -28,8 +28,8 @@ # Use the canonical paths from common.paths so the output location # matches what downstream stages (feature_build, feature_build_validation, # ...) expect. That resolves to -# ``~/.rpgkit/workspaces//data/feature_spec.json`` rather than the -# workspace-local ``.rpgkit/data/feature_spec.json`` this script used +# ``~/.cmind/workspaces//data/feature_spec.json`` rather than the +# workspace-local ``.cmind/data/feature_spec.json`` this script used # to compute on its own — a mismatch that previously broke the # feature_spec → feature_build handoff. from common.paths import FEATURE_SPEC_FILE @@ -381,9 +381,9 @@ def main(): if args.input_dir: input_dir = args.input_dir else: - # Try to find .rpgkit/data/feature_spec relative to current directory + # Try to find .cmind/data/feature_spec relative to current directory cwd = Path.cwd() - default_path = cwd / ".rpgkit" / "data" / "feature_spec" + default_path = cwd / ".cmind" / "data" / "feature_spec" if default_path.exists(): input_dir = default_path else: diff --git a/CoderMind/scripts/init_codebase.py b/CoderMind/scripts/init_codebase.py index bba85c6..f01be28 100644 --- a/CoderMind/scripts/init_codebase.py +++ b/CoderMind/scripts/init_codebase.py @@ -52,13 +52,13 @@ # Celery/Translations) plus the modern tool-cache entries (ruff, mypy, # pyright) and the common OS-junk lines (.DS_Store, Thumbs.db). Written # only when the user's existing ``.gitignore`` lacks ``__pycache__/``. -# * ``_GITIGNORE_RPGKIT_BLOCK`` — RPG-Kit-specific ignores (the entire -# ``.rpgkit/`` runtime tree, the ``.claude`` workspace symlink, and the -# ``.venv_dev/`` / ``.rpgkit_dev_env/`` venvs created by the codegen +# * ``_GITIGNORE_CMIND_BLOCK`` — CoderMind-specific ignores (the entire +# ``.cmind/`` runtime tree, the ``.claude`` workspace symlink, and the +# ``.venv_dev/`` / ``.cmind_dev_env/`` venvs created by the codegen # pipeline). Appended whenever the existing ``.gitignore`` lacks -# ``.rpgkit/``, regardless of whether Python ignores are already present. +# ``.cmind/``, regardless of whether Python ignores are already present. # This guarantees that an existing Python project getting bootstrapped -# by ``init_codebase`` still gets the RPG-Kit runtime files ignored. +# by ``init_codebase`` still gets the CoderMind runtime files ignored. _GITIGNORE_PYTHON_BLOCK = """# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -169,23 +169,23 @@ desktop.ini """ -_GITIGNORE_RPGKIT_BLOCK = """# RPG-Kit runtime workspace -# The entire .rpgkit/ tree is internal tooling state: logs, scripts copy, +_GITIGNORE_CMIND_BLOCK = """# CoderMind runtime workspace +# The entire .cmind/ tree is internal tooling state: logs, scripts copy, # state snapshots, trajectory traces, encoder/codegen JSON artifacts. # Treat it as ephemeral — none of it should be tracked in the project repo. -.rpgkit/ +.cmind/ -# RPG-Kit dev environments (created by codegen pipeline) +# CoderMind dev environments (created by codegen pipeline) .venv_dev/ -.rpgkit_dev_env/ +.cmind_dev_env/ -# RPG-Kit workspace symlink +# CoderMind workspace symlink .claude """ # Kept for backward compatibility with any external import — equivalent to # the full ``.gitignore`` written for a brand-new project. -GITIGNORE_CONTENT = _GITIGNORE_PYTHON_BLOCK + "\n" + _GITIGNORE_RPGKIT_BLOCK +GITIGNORE_CONTENT = _GITIGNORE_PYTHON_BLOCK + "\n" + _GITIGNORE_CMIND_BLOCK def _gitignore_has_python_block(existing: str) -> bool: @@ -193,10 +193,10 @@ def _gitignore_has_python_block(existing: str) -> bool: return "__pycache__/" in existing -def _gitignore_has_rpgkit_block(existing: str) -> bool: - """Heuristic: does an existing .gitignore already ignore .rpgkit/? +def _gitignore_has_cmind_block(existing: str) -> bool: + """Heuristic: does an existing .gitignore already ignore .cmind/? - Accepts the line-anchored form ``.rpgkit/`` or ``.rpgkit`` (without a + Accepts the line-anchored form ``.cmind/`` or ``.cmind`` (without a leading ``#``) so that earlier handwritten variants still count as "already configured" and don't get a duplicate block appended. """ @@ -204,7 +204,7 @@ def _gitignore_has_rpgkit_block(existing: str) -> bool: line = raw.strip() if not line or line.startswith("#"): continue - if line in (".rpgkit", ".rpgkit/", "/.rpgkit", "/.rpgkit/"): + if line in (".cmind", ".cmind/", "/.cmind", "/.cmind/"): return True return False @@ -214,16 +214,16 @@ def _gitignore_has_rpgkit_block(existing: str) -> bool: # ============================================================================ # # Removed: the -# previously-generated `repo/.claude/rules/rpgkit-codegen.md` and -# `repo/.github/instructions/rpgkit-codegen.instructions.md` files were +# previously-generated `repo/.claude/rules/cmind-codegen.md` and +# `repo/.github/instructions/cmind-codegen.instructions.md` files were # auto-loaded by Claude Code / Copilot for **every** session, contaminating # unrelated commands (rpg_edit, encode, plain Q&A) with codegen-only # instructions. The recovery-after-/compact concern is already handled by # `templates/commands/code_gen.md` itself, which the user re-invokes via -# `/rpgkit.code_gen`. +# `/cmind.code_gen`. # -# `rpgkit update` cleans up any stale `rpgkit-codegen.*` files left in older -# user workspaces (see src/rpgkit_cli/__init__.py). +# `cmind update` cleans up any stale `cmind-codegen.*` files left in older +# user workspaces (see src/cmind_cli/__init__.py). def load_json_file(path: Path) -> Dict[str, Any]: @@ -297,13 +297,13 @@ def create_readme(repo_path: Path, dry_run: bool = False) -> bool: def create_gitignore(repo_path: Path, dry_run: bool = False) -> bool: - """Create or update ``.gitignore`` to cover Python cache and RPG-Kit runtime. + """Create or update ``.gitignore`` to cover Python cache and CoderMind runtime. Behavior matrix: - * ``.gitignore`` does not exist → write the full template (Python + RPG-Kit blocks). - * Exists, lacks Python block → append Python + RPG-Kit blocks. - * Exists, has Python block, no RPG-Kit → append only the RPG-Kit block. + * ``.gitignore`` does not exist → write the full template (Python + CoderMind blocks). + * Exists, lacks Python block → append Python + CoderMind blocks. + * Exists, has Python block, no CoderMind → append only the CoderMind block. * Exists, has both blocks → no-op. Returns True when the file was created/modified, False when nothing changed @@ -320,19 +320,19 @@ def create_gitignore(repo_path: Path, dry_run: bool = False) -> bool: return False has_python = _gitignore_has_python_block(existing) - has_rpgkit = _gitignore_has_rpgkit_block(existing) + has_cmind = _gitignore_has_cmind_block(existing) - if has_python and has_rpgkit: + if has_python and has_cmind: return False # Already fully configured additions = "" if not has_python: additions += _GITIGNORE_PYTHON_BLOCK - if not has_rpgkit: + if not has_cmind: # Separate the two blocks with a blank line for readability. if additions: additions += "\n" - additions += _GITIGNORE_RPGKIT_BLOCK + additions += _GITIGNORE_CMIND_BLOCK if not additions: return False @@ -503,11 +503,11 @@ def init_codebase( # Ensure repo directory exists repo_path.mkdir(parents=True, exist_ok=True) - # Ensure .rpgkit/ runtime directories exist. This is normally already - # done by ``rpgkit init`` / ``rpgkit update`` (see - # ``rpgkit_cli.ensure_rpgkit_runtime_dirs``), but we mkdir here too as - # a safety net: a workspace created by an older rpgkit may lack - # ``.rpgkit/logs/``, in which case stage prompts that redirect with + # Ensure .cmind/ runtime directories exist. This is normally already + # done by ``cmind init`` / ``cmind update`` (see + # ``cmind_cli.ensure_cmind_runtime_dirs``), but we mkdir here too as + # a safety net: a workspace created by an older cmind may lack + # ``.cmind/logs/``, in which case stage prompts that redirect with # shell ``>`` fail before the Python process can recover. Creating # them here at code_gen bootstrap is harmless and idempotent. from common.paths import LOGS_DIR, DATA_DIR, TRAJECTORY_DIR @@ -678,7 +678,7 @@ def print_result(result: Dict[str, Any], json_output: bool = False): print(f"\n Initial commit: {result['commit_hash'][:8]}") print("\n " + "─" * 60) - print(f" Next step: Run /rpgkit.code_gen to start TDD") + print(f" Next step: Run /cmind.code_gen to start TDD") def main(): diff --git a/CoderMind/scripts/mcp_server.py b/CoderMind/scripts/mcp_server.py index a0e8e88..c9d5e17 100644 --- a/CoderMind/scripts/mcp_server.py +++ b/CoderMind/scripts/mcp_server.py @@ -1,4 +1,4 @@ -"""RPG-Kit MCP Server. +"""CoderMind MCP Server. Exposes RPG graph query tools via MCP (Model Context Protocol), allowing AI assistants to search, explore, and inspect RPG graphs interactively. @@ -10,16 +10,16 @@ - ``list_rpg_tree`` -- browse RPG feature tree structure The server communicates over stdio (the standard MCP transport for -CLI-based servers). It ships inside the ``rpgkit-cli`` wheel and is -launched by MCP clients via the ``rpgkit-mcp`` console script (which +CLI-based servers). It ships inside the ``cmind-cli`` wheel and is +launched by MCP clients via the ``cmind-mcp`` console script (which ``.mcp.json`` / ``.vscode/mcp.json`` register as the ``rpg-tools`` -command — see ``rpgkit_cli.entries:mcp_main``). +command — see ``cmind_cli.entries:mcp_main``). Run directly (for debugging):: - rpgkit-mcp [--rpg-file PATH] + cmind-mcp [--rpg-file PATH] # or equivalently: - rpgkit script mcp_server.py [--rpg-file PATH] + cmind script mcp_server.py [--rpg-file PATH] """ import json @@ -79,9 +79,9 @@ def _resolve_rpg_path() -> str: The default (``RPG_FILE``) is provided by :mod:`common.paths`, which resolves to - ``~/.rpgkit/workspaces//data/rpg.json`` for the current + ``~/.cmind/workspaces//data/rpg.json`` for the current workspace (discovered by walking up from cwd looking for - ``.rpgkit/config.toml``). Callers running ``rpgkit-mcp`` from any + ``.cmind/config.toml``). Callers running ``cmind-mcp`` from any subdirectory of a workspace therefore get the right RPG file automatically; ``--rpg-file`` is reserved for explicit overrides (test fixtures, alternative graphs, …). @@ -95,13 +95,13 @@ def _resolve_rpg_path() -> str: # Standard message returned to the AI agent when the RPG graph isn't ready -# (e.g. ``rpgkit init`` ran, but the encoder hasn't been run yet so +# (e.g. ``cmind init`` ran, but the encoder hasn't been run yet so # the resolved ``rpg.json`` doesn't exist). Kept short + actionable so # the agent will relay it verbatim to the user. The hint omits the # concrete directory path; the actual location is reported as the # ``rpg_file`` field of :func:`_unavailable_payload`. _ENCODE_HINT = ( - "RPG graph not generated yet. Ask the user to run **`/rpgkit.encode`** " + "RPG graph not generated yet. Ask the user to run **`/cmind.encode`** " "in this AI agent to build the workspace's `rpg.json`. Once it finishes, " "RPG tools will start working automatically on the next call — no need " "to restart the MCP server." @@ -138,10 +138,10 @@ def create_mcp_server(rpg_file: str): Registers 4 MCP tools: search, explore, detail, and tree. The engine is loaded **lazily**: if ``rpg_file`` doesn't yet exist - (typical first-run flow — ``rpgkit init`` finished but the user + (typical first-run flow — ``cmind init`` finished but the user hasn't run the encoder yet), the server still starts cleanly and every tool returns an actionable ``rpg_unavailable`` payload pointing - the user at ``/rpgkit.encode``. Once the encoder writes + the user at ``/cmind.encode``. Once the encoder writes ``rpg.json`` the next tool call picks it up automatically — no restart needed. This avoids the ``MCP error -32000: Connection closed`` failure mode that used to happen when the server exited @@ -192,7 +192,7 @@ def _unavailable_reason() -> str: "This server provides structured access to the Repository " "Program Graph (RPG) for the current workspace \u2014 a " "pre-computed, queryable index of the codebase built by " - "`/rpgkit.encode` and kept in sync with HEAD by a " + "`/cmind.encode` and kept in sync with HEAD by a " "post-commit hook.\n\n" "What the RPG knows about this repository:\n" " \u2022 The feature hierarchy: functional areas \u2192 " @@ -391,7 +391,7 @@ def list_rpg_tree( # --------------------------------------------------------------------------- -# Entry point: ``rpgkit-mcp`` console script (via rpgkit_cli.entries:mcp_main) +# Entry point: ``cmind-mcp`` console script (via cmind_cli.entries:mcp_main) # or direct ``python /mcp_server.py [--rpg-file PATH]`` for # debugging. # --------------------------------------------------------------------------- @@ -399,7 +399,7 @@ def list_rpg_tree( def main() -> None: """Run the MCP server over stdio. - Used by both the ``rpgkit-mcp`` console-script entry (which sets up + Used by both the ``cmind-mcp`` console-script entry (which sets up ``sys.path`` then imports and calls this function) and the direct ``python mcp_server.py`` invocation under ``__main__``. """ @@ -407,12 +407,12 @@ def main() -> None: # NOTE: do NOT sys.exit when the file is missing. The MCP transport # must stay up so the client can actually receive the # ``rpg_unavailable`` hint that tells the user to run - # ``/rpgkit.encode``. Exiting here used to surface as the opaque + # ``/cmind.encode``. Exiting here used to surface as the opaque # ``MCP error -32000: Connection closed`` on the client side. if not os.path.isfile(rpg_path): logger.warning( "RPG file not found: %s — server will start in degraded mode " - "and instruct the user to run /rpgkit.encode on the first tool call.", + "and instruct the user to run /cmind.encode on the first tool call.", rpg_path, ) diff --git a/CoderMind/scripts/plan_tasks.py b/CoderMind/scripts/plan_tasks.py index d205c06..94d19d9 100644 --- a/CoderMind/scripts/plan_tasks.py +++ b/CoderMind/scripts/plan_tasks.py @@ -7,8 +7,8 @@ - Validates that all units are covered without duplicates - Generates tasks.json with ordered implementation tasks -Input: .rpgkit/interfaces.json, .rpgkit/data_flow.json, .rpgkit/repo_rpg.json -Output: .rpgkit/tasks.json (ordered implementation tasks) +Input: .cmind/interfaces.json, .cmind/data_flow.json, .cmind/repo_rpg.json +Output: .cmind/tasks.json (ordered implementation tasks) """ import json @@ -1549,13 +1549,13 @@ def main(): # Load interfaces if not args.interfaces.exists(): print(f"\n Error: Interfaces file not found: {args.interfaces}") - print(" Please run /rpgkit.design_interfaces first.") + print(" Please run /cmind.design_interfaces first.") return 1 # Load data_flow if not args.data_flow.exists(): print(f"\n Error: Data flow file not found: {args.data_flow}") - print(" Please run /rpgkit.build_data_flow first.") + print(" Please run /cmind.build_data_flow first.") return 1 print(f"\n Loading interfaces from: {args.interfaces}") diff --git a/CoderMind/scripts/rpg/builder.py b/CoderMind/scripts/rpg/builder.py index 51dbdd7..1b92fdc 100644 --- a/CoderMind/scripts/rpg/builder.py +++ b/CoderMind/scripts/rpg/builder.py @@ -2,7 +2,7 @@ """RPG Builder. This module provides functionality to build RPG (Repository Program Graph) -from RPG-Kit's refactor_feature.json input format. +from CoderMind's refactor_feature.json input format. Key functions: - create_initial_rpg: Build RPG from component architecture @@ -17,7 +17,7 @@ def create_initial_rpg(repo_data: Dict[str, Any]) -> RPG: - """Create initial RPG from RPG-Kit's refactor_feature.json data. + """Create initial RPG from CoderMind's refactor_feature.json data. Args: repo_data: Dictionary from refactor_feature.json containing: diff --git a/CoderMind/scripts/rpg/models.py b/CoderMind/scripts/rpg/models.py index d399d6f..48db393 100644 --- a/CoderMind/scripts/rpg/models.py +++ b/CoderMind/scripts/rpg/models.py @@ -439,7 +439,7 @@ def __init__(self, repo_name: str, repo_info: str = "", excluded_files: List[str # Git sync state — see :meth:`set_git_meta`. ``None`` means the RPG # has never been linked to a git commit (e.g. brand-new RPG produced - # by ``/rpgkit.build_skeleton``). Persisted under top-level + # by ``/cmind.build_skeleton``). Persisted under top-level # ``"meta": {"git": {...}}`` by :meth:`to_dict`. self.git_meta: Optional[Dict[str, Optional[str]]] = None @@ -1080,7 +1080,7 @@ def get_node_by_feature_path(self, feature_path: str, sep: str = "/") -> Optiona def get_functional_areas(self) -> List[str]: """Return sorted names of top-level functional areas (L1 children of repo_node). - In RPG-Kit's tree structure, L1 children are directly accessed + In CoderMind's tree structure, L1 children are directly accessed via ``repo_node._children`` instead of scanning edges. Returns: @@ -1109,7 +1109,7 @@ def visualize_dir_map( """Visualize the RPG tree starting from L1 children. Ported from ZeroRepo ``RPG.visualize_dir_map`` (rpg.py:933-1158), - adapted for RPG-Kit's tree-based (``_children``) structure. + adapted for CoderMind's tree-based (``_children``) structure. Args: start: Starting node (Node or node ID). None = repo_node children. @@ -1400,7 +1400,7 @@ def delete_file_nodes(self, file_paths: List[str]) -> Dict[str, int]: that become childless **along the affected branches only**. Ported from ZeroRepo ``RPG.delete_file_nodes`` (rpg.py:569), - adapted for RPG-Kit's tree-based (``_children``/``_parent``) structure. + adapted for CoderMind's tree-based (``_children``/``_parent``) structure. Args: file_paths: Relative file paths to delete, e.g. @@ -1518,7 +1518,7 @@ def update_from_parsed_tree( - Clean up empty parent nodes. Ported from ZeroRepo ``RPG.update_from_parsed_tree`` (rpg.py:656), - adapted for RPG-Kit's tree-based structure. + adapted for CoderMind's tree-based structure. Args: parsed_tree: ``{rel_path: {unit_name: features, ...}, ...}`` @@ -2600,7 +2600,7 @@ def from_dict(cls, data: Dict[str, Any]) -> "RPG": """Restore RPG from a dictionary. Supports two formats: - - **RPG-Kit nested format**: Has ``root`` field with nested ``children``. + - **CoderMind nested format**: Has ``root`` field with nested ``children``. - **ZeroRepo flat format**: Has ``nodes`` array + ``edges`` for parent-child. Format is auto-detected by checking for the ``nodes`` key. @@ -2635,7 +2635,7 @@ def _restore_git_meta(rpg: "RPG", data: Dict[str, Any]) -> None: @classmethod def _from_tree_dict(cls, data: Dict[str, Any]) -> "RPG": - """Restore from RPG-Kit nested tree format (``root`` + ``children``).""" + """Restore from CoderMind nested tree format (``root`` + ``children``).""" repo_name = data.get("repo_name", "repo") repo_info = data.get("repo_info", "") excluded_files = data.get("excluded_files", []) diff --git a/CoderMind/scripts/rpg/service.py b/CoderMind/scripts/rpg/service.py index 0d401e4..de3565c 100644 --- a/CoderMind/scripts/rpg/service.py +++ b/CoderMind/scripts/rpg/service.py @@ -8,13 +8,13 @@ from rpg.service import RPGService - svc = RPGService.load('.rpgkit/data/repo_rpg.json') + svc = RPGService.load('.cmind/data/repo_rpg.json') svc.refresh_stage_edges("build_data_flow") src = svc.find_functional_area_by_name("Data Models") dst = svc.find_functional_area_by_name("Auth Routes") svc.add_dependency_edge(src, dst, EdgeType.REFERENCES, "build_data_flow", description="User model provides auth data") - svc.save('.rpgkit/data/repo_rpg.json') + svc.save('.cmind/data/repo_rpg.json') """ from __future__ import annotations @@ -534,7 +534,7 @@ def merge_dep_graph_from( # Environment variable that disables `meta.git` writes during sync. # Set in CI environments where the RPG is committed and you don't # want every CI run to advance `head_commit` to ephemeral CI commits. - _NO_GIT_META_ENV = "RPGKIT_NO_GIT_META" + _NO_GIT_META_ENV = "CMIND_NO_GIT_META" def sync_from_commit_diff( self, @@ -563,7 +563,7 @@ def sync_from_commit_diff( ========================= ========================================= After a successful run, advances ``meta.git`` to the current HEAD - (unless ``RPGKIT_NO_GIT_META=1`` or the workspace isn't a git + (unless ``CMIND_NO_GIT_META=1`` or the workspace isn't a git repo). The dep_graph is **always** persisted to ``save_path``; the RPG file itself is saved by the caller (this method only mutates ``self.rpg``). @@ -601,7 +601,7 @@ def sync_from_commit_diff( # ── Step 1: read current HEAD (silent-fail outside a git repo) ── current = read_head(workspace_root) # ``last_commit`` may be None for: - # * fresh RPG produced by /rpgkit.build_skeleton + # * fresh RPG produced by /cmind.build_skeleton # * legacy RPG without meta.git # * workspace not under git (current is None too) last_commit = (self.rpg.git_meta or {}).get("head_commit") @@ -1360,7 +1360,7 @@ def _dep_id_to_rpg_path(self, dep_nid: str, G) -> str: encoder and code-gen pipelines. Previously this method emitted the legacy ``::class X`` / ``::function X`` prefixed form, which would silently revert canonical paths to legacy on every - ``rpgkit update`` (a real bug — the prefix-stripped form on next read + ``cmind update`` (a real bug — the prefix-stripped form on next read produced a *different* lookup key and broke dep<->RPG correlation). The ``G`` argument is kept for backward compatibility with callers @@ -1379,7 +1379,7 @@ def _rpg_path_to_dep_id(self, rpg_path: str) -> Optional[str]: "models/user.py::User::login" -> "models/user.py:User.login" Legacy input is also tolerated so that rpg.json files written by - older encoder versions can still be aligned during ``rpgkit update`` + older encoder versions can still be aligned during ``cmind update`` without a separate migration step:: "models/user.py::class User" -> "models/user.py:User" diff --git a/CoderMind/scripts/rpg_agent/env/env.py b/CoderMind/scripts/rpg_agent/env/env.py index aaa6f6d..73f8649 100644 --- a/CoderMind/scripts/rpg_agent/env/env.py +++ b/CoderMind/scripts/rpg_agent/env/env.py @@ -11,9 +11,9 @@ - Replaced ``load_skeleton_from_repo`` / ``filter_non_test_py_files`` with repo-dir walking that builds a ``file2code`` dict (avoids importing the full RepoSkeleton build infra here). - - Replaced llama_index BM25 with RPG-Kit's lightweight + - Replaced llama_index BM25 with CoderMind's lightweight ``ModuleRetriever`` from ``bm25_model.py``. - - Uses RPG-Kit imports (``scripts.common.tools``, ``scripts.rpg_agent``). + - Uses CoderMind imports (``scripts.common.tools``, ``scripts.rpg_agent``). - ``parse_thinking_output`` inlined (tag-stripping helper). """ diff --git a/CoderMind/scripts/rpg_agent/ops/bm25_model.py b/CoderMind/scripts/rpg_agent/ops/bm25_model.py index 3b945cd..15459e2 100644 --- a/CoderMind/scripts/rpg_agent/ops/bm25_model.py +++ b/CoderMind/scripts/rpg_agent/ops/bm25_model.py @@ -2,7 +2,7 @@ """BM25 Search Model for RPG Agent. Provides BM25-based retrieval for code entities and code content, -using `rank_bm25` (already an RPG-Kit dependency) instead of the +using `rank_bm25` (already an CoderMind dependency) instead of the heavier llama_index-based implementation in RPG-ZeroRepo. Ported from: RPG-ZeroRepo/zerorepo/rpg_encoder/rpg_agent/ops/bm25_model.py diff --git a/CoderMind/scripts/rpg_agent/rpg_agent.py b/CoderMind/scripts/rpg_agent/rpg_agent.py index 4e0977e..1fdd010 100644 --- a/CoderMind/scripts/rpg_agent/rpg_agent.py +++ b/CoderMind/scripts/rpg_agent/rpg_agent.py @@ -9,12 +9,12 @@ Ported from: RPG-ZeroRepo/zerorepo/rpg_encoder/rpg_agent/rpg_agent.py -Adaptations for RPG-Kit: +Adaptations for CoderMind: - Uses ``LLMClient`` (``scripts.common.llm_client``) for CLI-based generation. - Uses ``Memory``, ``SystemMessage``, ``UserMessage``, ``AssistantMessage`` from ``scripts.common.llm_types``. - Uses ``Env`` from ``scripts.rpg_agent.env.env`` (no ``persist_dir`` param). - - Token usage keys aligned with RPG-Kit's ``LLMUsage.to_dict()`` output + - Token usage keys aligned with CoderMind's ``LLMUsage.to_dict()`` output (``input_tokens`` / ``output_tokens`` / ``total_tokens``). - Removed unused ``repo_skeleton`` / ``data_flow`` computations from ``load_task_to_env_prompt`` (they were computed but never used in diff --git a/CoderMind/scripts/rpg_agent/tools/search_node.py b/CoderMind/scripts/rpg_agent/tools/search_node.py index 5149e55..f72e1c2 100644 --- a/CoderMind/scripts/rpg_agent/tools/search_node.py +++ b/CoderMind/scripts/rpg_agent/tools/search_node.py @@ -6,7 +6,7 @@ Ported from: RPG-ZeroRepo/zerorepo/rpg_encoder/rpg_agent/tools/search_node.py Adaptations: - - RPG-Kit imports (scripts.common.tools, scripts.rpg_agent) + - CoderMind imports (scripts.common.tools, scripts.rpg_agent) - search_code_snippets takes file2code dict instead of repo_skeleton/bm25_retriever """ diff --git a/CoderMind/scripts/rpg_edit/__init__.py b/CoderMind/scripts/rpg_edit/__init__.py index 11b899a..f87b122 100644 --- a/CoderMind/scripts/rpg_edit/__init__.py +++ b/CoderMind/scripts/rpg_edit/__init__.py @@ -1,7 +1,7 @@ -"""RPG edit pipeline — CLI entry points for the ``/rpgkit.rpg_edit`` flow. +"""RPG edit pipeline — CLI entry points for the ``/cmind.rpg_edit`` flow. Each module is a standalone script meant to be invoked as -``rpgkit script rpg_edit/.py [args]``. They share the +``cmind script rpg_edit/.py [args]``. They share the ``common.paths`` / ``rpg`` / ``run_batch`` infrastructure that lives at ``scripts/`` and add ``scripts/`` (i.e. ``parent.parent``) to ``sys.path`` on import so the relative-import path stays predictable regardless of cwd. diff --git a/CoderMind/scripts/rpg_edit/apply.py b/CoderMind/scripts/rpg_edit/apply.py index deddd54..6df82b0 100644 --- a/CoderMind/scripts/rpg_edit/apply.py +++ b/CoderMind/scripts/rpg_edit/apply.py @@ -133,7 +133,7 @@ def main(): parser.add_argument("--rollback-branch", type=str, default=None, help="Together with --rollback: also force-delete the " "named git branch in the project repo (typically the " - "rpg-edit/ branch created by /rpgkit.rpg_edit). " + "rpg-edit/ branch created by /cmind.rpg_edit). " "Has no effect without --rollback.") parser.add_argument("--repo-dir", type=Path, default=None, help="Project repo for --rollback-branch operation. " diff --git a/CoderMind/scripts/rpg_edit/code.py b/CoderMind/scripts/rpg_edit/code.py index 6ce192d..c070be7 100644 --- a/CoderMind/scripts/rpg_edit/code.py +++ b/CoderMind/scripts/rpg_edit/code.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Apply EditPlan code_changes via a dedicated SubAgent (RPG-Driven). -This script implements Step 5c of /rpgkit.rpg_edit. Instead of the main +This script implements Step 5c of /cmind.rpg_edit. Instead of the main Agent freely editing code, it dispatches a SubAgent with a constrained prompt that treats the updated RPG nodes as authoritative ground truth. diff --git a/CoderMind/scripts/rpg_edit/review.py b/CoderMind/scripts/rpg_edit/review.py index c5ac4ef..55c25aa 100644 --- a/CoderMind/scripts/rpg_edit/review.py +++ b/CoderMind/scripts/rpg_edit/review.py @@ -6,9 +6,9 @@ data (callers, affected_files), NOT a full global review. Usage: - rpgkit script rpg_edit/review.py \ - --plan .rpgkit/data/rpg_edit_plan.json \ - --impact .rpgkit/data/rpg_edit_impact.json \ + cmind script rpg_edit/review.py \ + --plan .cmind/data/rpg_edit_plan.json \ + --impact .cmind/data/rpg_edit_impact.json \ --json The sub-agent will: @@ -340,8 +340,8 @@ def build_impact_review_prompt( pattern = " or ".join(test_patterns) pytest_cmd += f' -k "{pattern}" --timeout=30' - # Tool invocations route through the global ``rpgkit`` CLI (the - # scripts no longer live in the workspace). See ``rpgkit script`` + # Tool invocations route through the global ``cmind`` CLI (the + # scripts no longer live in the workspace). See ``cmind script`` # in docs/cli-reference.md. browser_tool = cmd_for("tools/browser.py") gui_tool = cmd_for("tools/gui.py") diff --git a/CoderMind/scripts/rpg_edit/save_plan.py b/CoderMind/scripts/rpg_edit/save_plan.py index 956870c..6d10177 100644 --- a/CoderMind/scripts/rpg_edit/save_plan.py +++ b/CoderMind/scripts/rpg_edit/save_plan.py @@ -2,13 +2,13 @@ """Save an EditPlan JSON document to ``RPG_EDIT_PLAN_FILE``. Reads JSON from stdin, validates that it parses, and writes it to -``~/.rpgkit/workspaces//data/rpg_edit_plan.json``. Slash-command +``~/.cmind/workspaces//data/rpg_edit_plan.json``. Slash-command templates use this so they never need to know the physical (home-dir) location of the workspace. Usage (typical AI-agent invocation):: - cat << 'PLAN_EOF' | rpgkit script rpg_edit/save_plan.py + cat << 'PLAN_EOF' | cmind script rpg_edit/save_plan.py { "feature_changes": [...], "code_changes": [...] } PLAN_EOF diff --git a/CoderMind/scripts/rpg_edit/validate.py b/CoderMind/scripts/rpg_edit/validate.py index 8ad5a96..08373ec 100644 --- a/CoderMind/scripts/rpg_edit/validate.py +++ b/CoderMind/scripts/rpg_edit/validate.py @@ -47,7 +47,7 @@ def main(): if not has_dep_graph and not args.dep_graph.exists(): result = {"type": "error", "error_code": "dep_graph_not_found", "message": f"dep_graph.json not found: {args.dep_graph}. " - "Run `rpgkit script update_graphs.py sync` " + "Run `cmind script update_graphs.py sync` " "to build it from the current code."} print(json.dumps(result) if args.json else f"Error: {result['message']}") return 1 diff --git a/CoderMind/scripts/rpg_encoder/check_encode.py b/CoderMind/scripts/rpg_encoder/check_encode.py index 63939e9..0c5e10b 100644 --- a/CoderMind/scripts/rpg_encoder/check_encode.py +++ b/CoderMind/scripts/rpg_encoder/check_encode.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Check Encode Script. -Inspect .rpgkit/data/rpg.json existence and validity to determine +Inspect .cmind/data/rpg.json existence and validity to determine the appropriate encode action. Decision rules: diff --git a/CoderMind/scripts/rpg_encoder/config.py b/CoderMind/scripts/rpg_encoder/config.py index 96520df..c6e2a7f 100644 --- a/CoderMind/scripts/rpg_encoder/config.py +++ b/CoderMind/scripts/rpg_encoder/config.py @@ -1,18 +1,18 @@ -"""RPG-Kit Workflow Configuration. +"""CoderMind Workflow Configuration. -Provides configuration management for RPG-Kit workflows. Settings are -loaded from ``.rpgkit/config.yaml`` (YAML) and merged with sensible +Provides configuration management for CoderMind workflows. Settings are +loaded from ``.cmind/config.yaml`` (YAML) and merged with sensible defaults. -This is an **original** RPG-Kit module -- it is NOT ported from +This is an **original** CoderMind module -- it is NOT ported from RPG-ZeroRepo. Key class: - ``RPGKitConfig`` -- immutable, validated configuration object. + ``CMindConfig`` -- immutable, validated configuration object. Typical usage:: - config = RPGKitConfig.load(repo_dir="/path/to/project") + config = CMindConfig.load(repo_dir="/path/to/project") print(config.workflow.default_mode) # "mixed" print(config.versioning.max_history) # 10 """ @@ -38,7 +38,7 @@ # --------------------------------------------------------------------------- CONFIG_FILE_NAME = "config.yaml" -RPGKIT_DIR_NAME = ".rpgkit" +CMIND_DIR_NAME = ".cmind" # Default values as module-level constants (accessible without instances) @@ -87,18 +87,18 @@ class WorkflowConfig: @dataclass(frozen=True) -class RPGKitConfig: - """Root configuration object for RPG-Kit. +class CMindConfig: + """Root configuration object for CoderMind. Attributes: workflow: Workflow-level settings (mode, encode, codegen, versioning). - rpgkit_dir: Absolute path to the ``.rpgkit`` directory. + cmind_dir: Absolute path to the ``.cmind`` directory. config_path: Absolute path to the loaded config file (may be ``None`` when no file was found and defaults were used). """ workflow: WorkflowConfig = field(default_factory=WorkflowConfig) - rpgkit_dir: str = "" + cmind_dir: str = "" config_path: Optional[str] = None # ------------------------------------------------------------------ @@ -106,8 +106,8 @@ class RPGKitConfig: # ------------------------------------------------------------------ @classmethod - def load(cls, repo_dir: str) -> "RPGKitConfig": - """Load configuration from ``/.rpgkit/config.yaml``. + def load(cls, repo_dir: str) -> "CMindConfig": + """Load configuration from ``/.cmind/config.yaml``. If the file does not exist or cannot be parsed, default values are returned (no exception is raised). @@ -116,10 +116,10 @@ def load(cls, repo_dir: str) -> "RPGKitConfig": repo_dir: Repository root directory. Returns: - Populated ``RPGKitConfig`` instance. + Populated ``CMindConfig`` instance. """ - rpgkit_dir = os.path.join(os.path.abspath(repo_dir), RPGKIT_DIR_NAME) - config_file = os.path.join(rpgkit_dir, CONFIG_FILE_NAME) + cmind_dir = os.path.join(os.path.abspath(repo_dir), CMIND_DIR_NAME) + config_file = os.path.join(cmind_dir, CONFIG_FILE_NAME) raw: Dict[str, Any] = {} loaded_path: Optional[str] = None @@ -147,27 +147,27 @@ def load(cls, repo_dir: str) -> "RPGKitConfig": workflow = _parse_workflow(raw.get("workflow", {})) return cls( workflow=workflow, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, config_path=loaded_path, ) @classmethod - def from_dict(cls, data: Dict[str, Any], rpgkit_dir: str = "") -> "RPGKitConfig": + def from_dict(cls, data: Dict[str, Any], cmind_dir: str = "") -> "CMindConfig": """Create a config from an in-memory dictionary. Useful for tests and programmatic construction. Args: data: Raw config dictionary (same shape as the YAML file). - rpgkit_dir: Override for ``.rpgkit`` directory path. + cmind_dir: Override for ``.cmind`` directory path. Returns: - Populated ``RPGKitConfig`` instance. + Populated ``CMindConfig`` instance. """ workflow = _parse_workflow(data.get("workflow", {})) return cls( workflow=workflow, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, config_path=None, ) @@ -200,7 +200,7 @@ def save(self, path: Optional[str] = None) -> str: Args: path: Target file path. Defaults to - ``/config.yaml``. + ``/config.yaml``. Returns: Absolute path of the written file. @@ -215,12 +215,12 @@ def save(self, path: Optional[str] = None) -> str: ) if path is None: - if not self.rpgkit_dir: + if not self.cmind_dir: raise ValueError( - "Cannot determine save path: rpgkit_dir is empty " + "Cannot determine save path: cmind_dir is empty " "and no explicit path was given." ) - path = os.path.join(self.rpgkit_dir, CONFIG_FILE_NAME) + path = os.path.join(self.cmind_dir, CONFIG_FILE_NAME) os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, "w", encoding="utf-8") as fh: diff --git a/CoderMind/scripts/rpg_encoder/refactor_tree.py b/CoderMind/scripts/rpg_encoder/refactor_tree.py index f3b64a6..238e868 100644 --- a/CoderMind/scripts/rpg_encoder/refactor_tree.py +++ b/CoderMind/scripts/rpg_encoder/refactor_tree.py @@ -4,7 +4,7 @@ a hierarchical RPG structure with three-level functional paths. Ported from RPG-ZeroRepo ``zerorepo/rpg_encoder/rpg_parsing/refactor_tree.py`` -with the following adaptations for RPG-Kit: +with the following adaptations for CoderMind: - Uses ``LLMClient`` from ``scripts.common.llm_client`` - Uses ``Memory`` / message types from ``scripts.common.llm_types`` - Uses utility functions from ``scripts.common.utils`` diff --git a/CoderMind/scripts/rpg_encoder/rpg_encoding.py b/CoderMind/scripts/rpg_encoder/rpg_encoding.py index ea6064f..6ff0017 100644 --- a/CoderMind/scripts/rpg_encoder/rpg_encoding.py +++ b/CoderMind/scripts/rpg_encoder/rpg_encoding.py @@ -10,13 +10,13 @@ 5. (Optional) Analyze data flow Ported from RPG-ZeroRepo ``zerorepo/rpg_encoder/rpg_parsing/rpg_encoding.py`` -with the following adaptations for RPG-Kit: +with the following adaptations for CoderMind: - Uses ``LLMClient`` from ``scripts.common.llm_client`` - Uses ``Memory`` / message types from ``scripts.common.llm_types`` - Uses utility functions from ``scripts.common.utils`` - Uses ``RPG`` / ``Node`` / ``NodeMetaData`` / ``NodeType`` from ``scripts.skeleton.rpg_models`` -- DataFlowAgent is **skipped** (RPG-Kit already has its own data-flow agent) +- DataFlowAgent is **skipped** (CoderMind already has its own data-flow agent) """ import json @@ -414,7 +414,7 @@ def parse_rpg_from_repo( refactor_context_window: int = 10, refactor_max_iters: int = 5, save_path: str = "", - # Data flow analysis is skipped (RPG-Kit has its own) + # Data flow analysis is skipped (CoderMind has its own) ) -> Tuple[RPG, Dict, str]: """Run the full RPG parsing pipeline. diff --git a/CoderMind/scripts/rpg_encoder/rpg_evolution.py b/CoderMind/scripts/rpg_encoder/rpg_evolution.py index 4bb8469..255e9a6 100644 --- a/CoderMind/scripts/rpg_encoder/rpg_evolution.py +++ b/CoderMind/scripts/rpg_encoder/rpg_evolution.py @@ -12,7 +12,7 @@ 6. Sync skeleton feature paths Ported from RPG-ZeroRepo ``zerorepo/rpg_encoder/rpg_parsing/rpg_evolution.py`` -with the following adaptations for RPG-Kit: +with the following adaptations for CoderMind: - No ``RepoSkeleton`` / ``FileNode`` dependency -- uses simplified skeleton loading via ``os.walk`` (same pattern as ``RPGParser``). - Uses ``LLMClient`` from ``scripts.common.llm_client`` @@ -292,7 +292,7 @@ class RPGEvolution: - Provides detailed logging and statistics Ported from RPG-ZeroRepo ``rpg_evolution.py`` :class:`RPGEvolution`, - adapted for RPG-Kit infrastructure. + adapted for CoderMind infrastructure. """ # ------------------------------------------------------------------ @@ -337,7 +337,7 @@ def _update_dep_graph_index( in-memory ``rpg.dep_graph`` — leaving ``dep_graph.json`` stale whenever the encoder wrote ``rpg.json`` separately afterwards. That drift caused MCP-server / ``update_graphs.py status`` reads - to return inconsistent data after ``/rpgkit.update_rpg``. + to return inconsistent data after ``/cmind.update_rpg``. Args: rpg: The RPG to attach the rebuilt dep_graph to. diff --git a/CoderMind/scripts/rpg_encoder/run_encode.py b/CoderMind/scripts/rpg_encoder/run_encode.py index 3b8cc84..38e30af 100644 --- a/CoderMind/scripts/rpg_encoder/run_encode.py +++ b/CoderMind/scripts/rpg_encoder/run_encode.py @@ -2,13 +2,13 @@ """Run Encode Script. Full repository encode: calls RPGParser.parse_rpg_from_repo() to build -an RPG from scratch and saves it to .rpgkit/data/rpg.json. +an RPG from scratch and saves it to .cmind/data/rpg.json. Prints a single JSON result to stdout with status and statistics. Usage: - rpgkit script rpg_encoder/run_encode.py --json - rpgkit script rpg_encoder/run_encode.py --repo-dir ./my-project + cmind script rpg_encoder/run_encode.py --json + cmind script rpg_encoder/run_encode.py --repo-dir ./my-project """ import json @@ -25,7 +25,7 @@ if str(_script_dir) not in sys.path: sys.path.insert(0, str(_script_dir)) -from common.paths import RPG_FILE, DEP_GRAPH_FILE, RPG_HTML_FILE, WORKSPACE_ROOT, ensure_rpgkit_dir # noqa: E402 +from common.paths import RPG_FILE, DEP_GRAPH_FILE, RPG_HTML_FILE, WORKSPACE_ROOT, ensure_cmind_dir # noqa: E402 from common.trajectory import Trajectory # noqa: E402 @@ -40,7 +40,7 @@ def run_encode( Args: repo_dir: Code directory to scan. Defaults to :data:`common.paths.WORKSPACE_ROOT` — the directory the - user ran ``rpgkit init --here`` in (their existing source + user ran ``cmind init --here`` in (their existing source repo). Pass an explicit path to override. repo_name: Override the inferred repo name. output: Override the RPG output path. @@ -165,8 +165,8 @@ def run_encode( viz_data = load_rpg(output) html_content = generate_html(viz_data) # rpg.html is a user-facing artefact: keep it in the - # workspace's .rpgkit/reports/ rather than next to the - # machine-side rpg.json under ~/.rpgkit/workspaces//. + # workspace's .cmind/reports/ rather than next to the + # machine-side rpg.json under ~/.cmind/workspaces//. RPG_HTML_FILE.parent.mkdir(parents=True, exist_ok=True) viz_output = str(RPG_HTML_FILE) RPG_HTML_FILE.write_text(html_content, encoding="utf-8") @@ -211,8 +211,8 @@ def main(): default=None, help=( "Repository directory to scan. Defaults to the workspace " - "root (the directory containing ``.rpgkit/``, i.e. where " - "``rpgkit init --here`` was run)." + "root (the directory containing ``.cmind/``, i.e. where " + "``cmind init --here`` was run)." ), ) parser.add_argument("--repo-name", default=None, help="Repository name") @@ -229,7 +229,7 @@ def main(): ) args = parser.parse_args() - ensure_rpgkit_dir() + ensure_cmind_dir() result = run_encode( repo_dir=args.repo_dir, repo_name=args.repo_name, diff --git a/CoderMind/scripts/rpg_encoder/run_update_rpg.py b/CoderMind/scripts/rpg_encoder/run_update_rpg.py index 67a6071..6d62336 100644 --- a/CoderMind/scripts/rpg_encoder/run_update_rpg.py +++ b/CoderMind/scripts/rpg_encoder/run_update_rpg.py @@ -7,8 +7,8 @@ Prints a single JSON result to stdout with status and diff statistics. Usage: - rpgkit script rpg_encoder/run_update_rpg.py --json \\ - --rpg-file .rpgkit/data/rpg.json --last-repo-dir ./old-version + cmind script rpg_encoder/run_update_rpg.py --json \\ + --rpg-file .cmind/data/rpg.json --last-repo-dir ./old-version """ import json @@ -53,14 +53,14 @@ def run_update_rpg( this baseline. """ # ``cur_repo_dir`` defaults to ``WORKSPACE_ROOT`` — the directory - # the user ran ``rpgkit init --here`` in (their existing source + # the user ran ``cmind init --here`` in (their existing source # repo). Pass an explicit path to override. if cur_repo_dir is None: cur_repo_dir = str(WORKSPACE_ROOT) cur_repo_dir = os.path.abspath(cur_repo_dir) last_repo_dir = os.path.abspath(last_repo_dir) rpg_file = os.path.abspath(rpg_file) - # ``dep_graph_path`` defaults to the standard ``.rpgkit/data/dep_graph.json`` + # ``dep_graph_path`` defaults to the standard ``.cmind/data/dep_graph.json`` # location so that ``run_update_rpg.py`` (CLI) and the pre-commit # hook agree on a single canonical file. if dep_graph_path is None: @@ -218,7 +218,7 @@ def main(): default=None, help=( "Current repository directory. Defaults to the workspace " - "root (the directory containing ``.rpgkit/``)." + "root (the directory containing ``.cmind/``)." ), ) parser.add_argument("--last-repo-dir", "-l", required=True, help="Previous version repo directory") @@ -227,7 +227,7 @@ def main(): "--dep-graph", default=None, help=( - "Path to write dep_graph.json (default: .rpgkit/data/dep_graph.json). " + "Path to write dep_graph.json (default: .cmind/data/dep_graph.json). " "Must match the path used by the pre-commit sync hook to avoid drift." ), ) diff --git a/CoderMind/scripts/rpg_encoder/semantic_parsing.py b/CoderMind/scripts/rpg_encoder/semantic_parsing.py index db8139f..c6c884f 100644 --- a/CoderMind/scripts/rpg_encoder/semantic_parsing.py +++ b/CoderMind/scripts/rpg_encoder/semantic_parsing.py @@ -10,7 +10,7 @@ 5. Deduplicate summaries Ported from RPG-ZeroRepo ``zerorepo/rpg_encoder/rpg_parsing/semantic_parsing.py`` -with the following adaptations for RPG-Kit: +with the following adaptations for CoderMind: - Uses ``LLMClient`` from ``scripts.common.llm_client`` - Uses ``Memory`` / message types from ``scripts.common.llm_types`` - Uses utility functions from ``scripts.common.utils`` diff --git a/CoderMind/scripts/rpg_encoder/version_control.py b/CoderMind/scripts/rpg_encoder/version_control.py index d2c7252..2ac35ba 100644 --- a/CoderMind/scripts/rpg_encoder/version_control.py +++ b/CoderMind/scripts/rpg_encoder/version_control.py @@ -1,10 +1,10 @@ """RPG Version Control. Manages versioned snapshots of RPG state (``rpg.json``) inside the -``.rpgkit/data/history/`` directory. Each snapshot is a self-contained +``.cmind/data/history/`` directory. Each snapshot is a self-contained JSON file with metadata (version number, timestamp, message, source). -This is an **original** RPG-Kit module -- it is NOT ported from +This is an **original** CoderMind module -- it is NOT ported from RPG-ZeroRepo. Key class: @@ -12,7 +12,7 @@ Typical usage:: - vc = RPGVersionControl(rpgkit_dir=".rpgkit") + vc = RPGVersionControl(cmind_dir=".cmind") v = vc.save_version(rpg, message="Initial encode") old_rpg = vc.rollback(version=1) diff = vc.diff(version1=1, version2=2) @@ -75,7 +75,7 @@ def _parse_version_from_filename(filename: str) -> Optional[int]: class RPGVersionControl: """Manage versioned snapshots of the RPG. - Versions are stored as ``/data/history/rpg.v.json`` + Versions are stored as ``/data/history/rpg.v.json`` where *N* is a monotonically increasing integer starting from 1. Each version file contains: @@ -86,13 +86,13 @@ class RPGVersionControl: - ``rpg``: the full RPG dict (``RPG.to_dict()``) Args: - rpgkit_dir: Path to the ``.rpgkit`` directory. + cmind_dir: Path to the ``.cmind`` directory. max_history: Maximum number of versions to keep (0 = unlimited). """ - def __init__(self, rpgkit_dir: str, max_history: int = 10): - self.rpgkit_dir = os.path.abspath(rpgkit_dir) - self.data_dir = os.path.join(self.rpgkit_dir, DATA_DIR_NAME) + def __init__(self, cmind_dir: str, max_history: int = 10): + self.cmind_dir = os.path.abspath(cmind_dir) + self.data_dir = os.path.join(self.cmind_dir, DATA_DIR_NAME) self.history_dir = os.path.join(self.data_dir, HISTORY_DIR_NAME) self.max_history = max_history diff --git a/CoderMind/scripts/rpg_encoder/workflow.py b/CoderMind/scripts/rpg_encoder/workflow.py index 56981ed..aeda344 100644 --- a/CoderMind/scripts/rpg_encoder/workflow.py +++ b/CoderMind/scripts/rpg_encoder/workflow.py @@ -3,7 +3,7 @@ Bridges the *forward* (requirements -> code) and *reverse* (code -> RPG) pipelines so that they can be composed seamlessly. -This is an **original** RPG-Kit module -- it is NOT ported from +This is an **original** CoderMind module -- it is NOT ported from RPG-ZeroRepo. Key class: @@ -51,7 +51,7 @@ method_node_path, ) -from .config import RPGKitConfig +from .config import CMindConfig from .version_control import RPGVersionControl, RPG_FILE_NAME from common.rpg_io import atomic_write_rpg @@ -68,7 +68,7 @@ class WorkflowIntegration: All public methods are class-methods or static-methods so that no persistent state is required. Configuration is read from the - ``RPGKitConfig`` object when needed. + ``CMindConfig`` object when needed. Design rationale: - **No modifications to existing forward-flow code.** The forward @@ -308,7 +308,7 @@ def merge_generated_code( @staticmethod def save_rpg( rpg: RPG, - rpgkit_dir: str, + cmind_dir: str, message: str = "", source: str = "mixed", version_control: bool = True, @@ -317,7 +317,7 @@ def save_rpg( Args: rpg: The RPG instance to save. - rpgkit_dir: Path to the ``.rpgkit`` directory. + cmind_dir: Path to the ``.cmind`` directory. message: Description for the version snapshot. source: Source label (``"generated"``/``"encoded"``/``"mixed"``). version_control: Whether to also save a versioned snapshot. @@ -325,7 +325,7 @@ def save_rpg( Returns: Dictionary with ``rpg_path`` and optional ``version``. """ - data_dir = os.path.join(rpgkit_dir, "data") + data_dir = os.path.join(cmind_dir, "data") os.makedirs(data_dir, exist_ok=True) rpg_path = os.path.join(data_dir, RPG_FILE_NAME) @@ -344,11 +344,11 @@ def save_rpg( if version_control: try: - config = RPGKitConfig.load( - os.path.dirname(rpgkit_dir) + config = CMindConfig.load( + os.path.dirname(cmind_dir) ) vc = RPGVersionControl( - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, max_history=config.workflow.versioning.max_history, ) version = vc.save_version(rpg, message=message, source=source) @@ -360,20 +360,20 @@ def save_rpg( return result # ------------------------------------------------------------------ - # load_rpg (convenience: load from .rpgkit/data/rpg.json) + # load_rpg (convenience: load from .cmind/data/rpg.json) # ------------------------------------------------------------------ @staticmethod - def load_rpg(rpgkit_dir: str) -> Optional[RPG]: - """Load the current RPG from ``/data/rpg.json``. + def load_rpg(cmind_dir: str) -> Optional[RPG]: + """Load the current RPG from ``/data/rpg.json``. Args: - rpgkit_dir: Path to the ``.rpgkit`` directory. + cmind_dir: Path to the ``.cmind`` directory. Returns: The loaded RPG, or ``None`` if the file does not exist. """ - rpg_path = os.path.join(rpgkit_dir, "data", RPG_FILE_NAME) + rpg_path = os.path.join(cmind_dir, "data", RPG_FILE_NAME) if not os.path.isfile(rpg_path): return None diff --git a/CoderMind/scripts/rpg_visualize.py b/CoderMind/scripts/rpg_visualize.py index 9e6a7de..387367e 100644 --- a/CoderMind/scripts/rpg_visualize.py +++ b/CoderMind/scripts/rpg_visualize.py @@ -1877,7 +1877,7 @@ def main(): parser = argparse.ArgumentParser(description="Visualize RPG as interactive graph") parser.add_argument("rpg_file", nargs="?", default=str(RPG_FILE), - help="Path to rpg.json (default: .rpgkit/data/rpg.json)") + help="Path to rpg.json (default: .cmind/data/rpg.json)") parser.add_argument("--dep-graph", default=None, help="Path to dep_graph.json (default: dep_graph_file field or sibling dep_graph.json)") parser.add_argument("-o", "--output", default=None, diff --git a/CoderMind/scripts/run_batch.py b/CoderMind/scripts/run_batch.py index 86bbf88..43622aa 100644 --- a/CoderMind/scripts/run_batch.py +++ b/CoderMind/scripts/run_batch.py @@ -417,7 +417,7 @@ def _refresh_dep_graph_safe( The codegen pipeline does its own commit hygiene (each batch lands on its own git branch then merges), so this entry point intentionally does NOT advance ``meta.git`` — that's owned by the pre-commit / - post-merge hooks and ``/rpgkit.update_rpg``. + post-merge hooks and ``/cmind.update_rpg``. """ try: import sys @@ -995,7 +995,7 @@ def main() -> int: if isinstance(handler, logging.StreamHandler) and not isinstance(handler, logging.FileHandler): handler.setLevel(log_level) - # File handler: capture DEBUG records to .rpgkit/logs/code_gen.log via + # File handler: capture DEBUG records to .cmind/logs/code_gen.log via # the shared helper (idempotent; degrades gracefully on read-only FS). from common.logging_setup import setup_file_logging setup_file_logging("code_gen") diff --git a/CoderMind/scripts/smoke_test.py b/CoderMind/scripts/smoke_test.py index 86e3233..e74bacf 100644 --- a/CoderMind/scripts/smoke_test.py +++ b/CoderMind/scripts/smoke_test.py @@ -107,7 +107,7 @@ def _get_python_exe(repo_path: Path) -> str: def _find_source_files(repo_path: Path) -> List[Path]: """Find all .py source files (excluding tests, venv, __pycache__).""" skip_dirs = {".venv_dev", ".venv", "venv", "__pycache__", ".git", - ".rpgkit", ".pytest_cache", "node_modules"} + ".cmind", ".pytest_cache", "node_modules"} result = [] for py_file in repo_path.rglob("*.py"): parts = set(py_file.relative_to(repo_path).parts) diff --git a/CoderMind/scripts/summary_skeleton.py b/CoderMind/scripts/summary_skeleton.py index 34899b5..b44361a 100644 --- a/CoderMind/scripts/summary_skeleton.py +++ b/CoderMind/scripts/summary_skeleton.py @@ -417,7 +417,7 @@ def main() -> int: input_path = Path(args.input) if not input_path.exists(): print(f"Error: Skeleton file not found: {input_path}") - print("Please run /rpgkit.build_skeleton first.") + print("Please run /cmind.build_skeleton first.") return 1 skeleton_data = load_skeleton(input_path) diff --git a/CoderMind/scripts/tools/browser.py b/CoderMind/scripts/tools/browser.py index 54eab05..2990855 100644 --- a/CoderMind/scripts/tools/browser.py +++ b/CoderMind/scripts/tools/browser.py @@ -38,7 +38,7 @@ # Constants # --------------------------------------------------------------------------- -DEFAULT_OUTPUT_DIR = ".rpgkit/tmp/screenshots" +DEFAULT_OUTPUT_DIR = ".cmind/tmp/screenshots" DEFAULT_TIMEOUT = 10000 # 10s per Playwright operation SCRIPT_TIMEOUT = 60 # 60s hard limit for run-script @@ -350,7 +350,7 @@ def cmd_inspect(url: str, width: int = 1280, height: int = 720): and collects all useful information, saving files for later analysis. Output: - - Screenshot (.png) and HTML (.html) saved to .rpgkit/tmp/screenshots/ + - Screenshot (.png) and HTML (.html) saved to .cmind/tmp/screenshots/ - Prints: request URL, actual URL, title, status - Prints: all links with visibility - Prints: all forms with fields @@ -554,7 +554,7 @@ def cmd_run_script(url: str, script: str, timeout: int = SCRIPT_TIMEOUT): Safety: - Hard timeout (default 60s) via SIGALRM - Browser always cleaned up via context manager - - On error: automatic screenshot saved to .rpgkit/tmp/screenshots/ + - On error: automatic screenshot saved to .cmind/tmp/screenshots/ - Restricted builtins (no os, subprocess, sys access) """ with open_browser() as (pw, browser): @@ -727,7 +727,7 @@ def main(): %(prog)s inspect http://localhost:5000/login # Screenshot only - %(prog)s screenshot http://localhost:5000/ -o .rpgkit/tmp/home.png + %(prog)s screenshot http://localhost:5000/ -o .cmind/tmp/home.png # Page structure %(prog)s accessibility-tree http://localhost:5000/ @@ -749,7 +749,7 @@ def main(): page.wait_for_load_state("networkidle") print("URL after login:", page.url) print("Title:", page.title()) -page.screenshot(path=".rpgkit/tmp/after_login.png", full_page=True) +page.screenshot(path=".cmind/tmp/after_login.png", full_page=True) ' """, ) diff --git a/CoderMind/scripts/tools/gui.py b/CoderMind/scripts/tools/gui.py index 4759fe9..ed1093c 100644 --- a/CoderMind/scripts/tools/gui.py +++ b/CoderMind/scripts/tools/gui.py @@ -41,12 +41,12 @@ # Constants # --------------------------------------------------------------------------- -DEFAULT_OUTPUT_DIR = ".rpgkit/tmp/screenshots" +DEFAULT_OUTPUT_DIR = ".cmind/tmp/screenshots" DEFAULT_DISPLAY = ":99" DEFAULT_SCREEN_SIZE = "1280x720x24" SCRIPT_TIMEOUT = 60 LAUNCH_WAIT = 3 # seconds to wait after launching app -_PID_FILE = ".rpgkit/tmp/gui_app.pid" # persist app PID across CLI calls +_PID_FILE = ".cmind/tmp/gui_app.pid" # persist app PID across CLI calls # Track managed processes for cleanup (in-process only; PID file for cross-process) _managed_pids: dict = {} # label -> pid diff --git a/CoderMind/scripts/update_graphs.py b/CoderMind/scripts/update_graphs.py index df0f981..b970db2 100644 --- a/CoderMind/scripts/update_graphs.py +++ b/CoderMind/scripts/update_graphs.py @@ -13,11 +13,11 @@ full AST scan + mappings + edges (legacy, use 'sync' instead) Usage: - rpgkit script update_graphs.py dep --json - rpgkit script update_graphs.py enrich --json - rpgkit script update_graphs.py enrich --file models/user.py --dry-run --json - rpgkit script update_graphs.py sync --json - rpgkit script update_graphs.py update-rpg --json + cmind script update_graphs.py dep --json + cmind script update_graphs.py enrich --json + cmind script update_graphs.py enrich --file models/user.py --dry-run --json + cmind script update_graphs.py sync --json + cmind script update_graphs.py update-rpg --json """ import argparse @@ -37,13 +37,13 @@ # Shared message used by every subcommand that requires an existing # ``rpg.json`` (sync, update-rpg, ...). Surfaces in two places: -# * ``.rpgkit/logs/update_rpg.log`` for the asynchronous post-commit +# * ``.cmind/logs/update_rpg.log`` for the asynchronous post-commit # phase — where it's the user's only diagnostic. # * stdout / JSON output for direct CLI invocations. # Keep the message single-line so it survives JSON serialisation cleanly # and stays easy to grep. _RPG_MISSING_MSG = ( - "rpg.json not found at {rpg_path}. Run /rpgkit.encode in your AI agent " + "rpg.json not found at {rpg_path}. Run /cmind.encode in your AI agent " "to generate it; the post-commit hook will resume keeping it in sync " "on the next commit." ) @@ -104,7 +104,7 @@ def _refresh_rpg_html(rpg_path: Path) -> dict: data = load_rpg(str(rpg_path)) html_content = generate_html(data) # rpg.html is a user-facing artefact: write it to the - # workspace's .rpgkit/reports/ (the home-side data/ holds + # workspace's .cmind/reports/ (the home-side data/ holds # only machine-consumed JSON). This mirrors run_encode.py. RPG_HTML_FILE.parent.mkdir(parents=True, exist_ok=True) RPG_HTML_FILE.write_text(html_content, encoding="utf-8") @@ -390,7 +390,7 @@ def cmd_update_rpg( Designed for post-commit background invocation via ``setsid``:: setsid env -u GIT_INDEX_FILE -u GIT_DIR sh -c \ - "cd ; rpgkit script update_graphs.py update-rpg --json >> log 2>&1" & + "cd ; cmind script update_graphs.py update-rpg --json >> log 2>&1" & Requires: - rpg.json exists (encode has been run) @@ -431,7 +431,7 @@ def cmd_update_rpg( ) # Create temporary worktree for previous commit. - worktree_dir = tempfile.mkdtemp(prefix="rpgkit_prev_") + worktree_dir = tempfile.mkdtemp(prefix="cmind_prev_") try: wt_proc = subprocess.run( ["git", "worktree", "add", worktree_dir, prev_ref, "--detach", "-q"], @@ -494,7 +494,7 @@ def _auto_detect_code_dir(workspace_root: str, code_dir_arg: str = None) -> str: Returns the workspace root by default — matching the encoder entry points (``run_encode.py`` / ``run_update_rpg.py``) which also default to ``WORKSPACE_ROOT``. This keeps all 3 entry - points consistent in encoder mode (``rpgkit init --here`` inside + points consistent in encoder mode (``cmind init --here`` inside an existing repo). An explicit ``code_dir_arg`` always wins; pass it when scanning @@ -610,18 +610,18 @@ def _format_status_for_agent(status: dict) -> str: edges = status.get("rpg_edges", "?") repo = status.get("repo_name") or "unknown" lines.append( - f"[RPG-Kit] Repository Program Graph is available " + f"[CoderMind] Repository Program Graph is available " f"(repo={repo}, nodes={nodes}, edges={edges})." ) if status.get("dep_graph_exists") and "dep_graph_error" not in status: dn = status.get("dep_nodes", "?") de = status.get("dep_edges", "?") lines.append( - f"[RPG-Kit] Dependency graph: {dn} nodes, {de} edges." + f"[CoderMind] Dependency graph: {dn} nodes, {de} edges." ) elif "dep_graph_error" in status: lines.append( - f"[RPG-Kit] Dependency graph unavailable (parse error: " + f"[CoderMind] Dependency graph unavailable (parse error: " f"{status['dep_graph_error']})." ) @@ -641,7 +641,7 @@ def _branch_suffix(branch): if last_short and cur_short: if in_sync: lines.append( - f"[RPG-Kit] Last synced at commit {last_short}" + f"[CoderMind] Last synced at commit {last_short}" f"{_branch_suffix(cur_branch or last_branch)} " "(in sync with current HEAD)." ) @@ -656,17 +656,17 @@ def _branch_suffix(branch): f" (branch changed: '{last_branch}' → '{cur_branch}')" ) lines.append( - f"[RPG-Kit] Last synced at commit {last_short}" + f"[CoderMind] Last synced at commit {last_short}" f"{_branch_suffix(last_branch)}; " f"current HEAD is {cur_short}" f"{_branch_suffix(cur_branch)}{branch_note}. " - "Run /rpgkit.update_rpg " + "Run /cmind.update_rpg " "(or commit to trigger the pre-commit sync hook) to " "refresh the graph." ) elif last_short and not cur_short: lines.append( - f"[RPG-Kit] Last synced at commit {last_short}" + f"[CoderMind] Last synced at commit {last_short}" f"{_branch_suffix(last_branch)}; git status " "for the current workspace is unavailable." ) @@ -702,15 +702,15 @@ def _branch_suffix(branch): # File present but unreadable: tell the agent the graph is # NOT available so it doesn't waste a turn calling rpg-tools. lines.append( - f"[RPG-Kit] RPG file at {status.get('rpg_path')} could not " + f"[CoderMind] RPG file at {status.get('rpg_path')} could not " f"be parsed (error: {status['rpg_error']}). Graph-powered " "navigation is unavailable until it is rebuilt. Run " - "/rpgkit.encode to regenerate it." + "/cmind.encode to regenerate it." ) else: lines.append( - "[RPG-Kit] No RPG found at " - f"{status.get('rpg_path')}. Run /rpgkit.encode to build the " + "[CoderMind] No RPG found at " + f"{status.get('rpg_path')}. Run /cmind.encode to build the " "Repository Program Graph and enable graph-powered code " "navigation via the rpg-tools MCP server." ) @@ -820,10 +820,10 @@ def _add_common(p): # For background hook processes (setsid), cwd may not be the # workspace root. Use the rpg file path to infer it: - # rpg_path = /.rpgkit/data/rpg.json → workspace = rpg_path/../../../ - if not os.path.isdir(os.path.join(workspace_root, ".rpgkit")): + # rpg_path = /.cmind/data/rpg.json → workspace = rpg_path/../../../ + if not os.path.isdir(os.path.join(workspace_root, ".cmind")): inferred = args.rpg.resolve().parent.parent.parent - if (inferred / ".rpgkit").is_dir(): + if (inferred / ".cmind").is_dir(): workspace_root = str(inferred) os.chdir(workspace_root) diff --git a/CoderMind/src/rpgkit_cli/__init__.py b/CoderMind/src/cmind_cli/__init__.py similarity index 89% rename from CoderMind/src/rpgkit_cli/__init__.py rename to CoderMind/src/cmind_cli/__init__.py index 5e0b1d7..a878457 100644 --- a/CoderMind/src/rpgkit_cli/__init__.py +++ b/CoderMind/src/cmind_cli/__init__.py @@ -1,15 +1,15 @@ -"""RPG-Kit CLI - Setup tool for RPG-Kit projects. +"""CoderMind CLI - Provision and manage Repository Planning Graph (RPG) workspaces for AI coding agents. Usage: - uvx rpgkit-cli init - uvx rpgkit-cli init . - uvx rpgkit-cli init --here + uvx cmind-cli init + uvx cmind-cli init . + uvx cmind-cli init --here Or install globally: - uv tool install rpgkit-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=RPG-Kit" - rpgkit init - rpgkit init . - rpgkit init --here + uv tool install cmind-cli --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" + cmind init + cmind init . + cmind init --here """ import os @@ -62,19 +62,19 @@ # Default fallback values — only used when git remote and pyproject.toml are unavailable _FALLBACK_REPO_OWNER = "microsoft" _FALLBACK_REPO_NAME = "RPG-ZeroRepo" -_RPGKIT_RELEASE_TAG_PREFIX = "rpgkit-v" +_CMIND_RELEASE_TAG_PREFIX = "cmind-v" # --------------------------------------------------------------------------- # DEPRECATED: GitHub release-zip provisioning helpers. # -# As of v0.1.4 ``rpgkit init`` / ``rpgkit update`` are bundle-only and no +# As of v0.1.4 ``cmind init`` / ``cmind update`` are bundle-only and no # longer fetch templates from GitHub releases at runtime — users upgrade # the CLI itself to pick up newer prompts. The helpers below # (``_parse_github_owner_repo``, ``_github_token``, # ``_github_auth_headers``, ``_parse_rate_limit_headers``, # ``_format_rate_limit_error``, ``_is_private_repo``, -# ``_get_asset_download_url``, ``_fetch_latest_rpgkit_release``, +# ``_get_asset_download_url``, ``_fetch_latest_cmind_release``, # ``download_template_from_github``, ``_download_and_extract_release_zip``) # are kept temporarily so the change is reversible and so any third-party # callers don't break on upgrade. They are slated for removal in v0.2.0 @@ -106,7 +106,7 @@ def _parse_github_owner_repo(url: str) -> Tuple[str, str] | None: def _get_repo_info() -> Tuple[str, str]: - """Resolve the GitHub owner/repo for RPG-Kit template downloads. + """Resolve the GitHub owner/repo for CoderMind template downloads. Priority: 1. git remote 'upstream' (fork scenario — points to original repo) @@ -322,29 +322,29 @@ def _format_rate_limit_error(status_code: int, headers: httpx.Headers, url: str) # Bundle mode (packaged assets) — added in 0.1.3 # --------------------------------------------------------------------------- # -# rpgkit-cli ships ``scripts/`` and ``templates/commands/`` as packaged -# assets under ``rpgkit_cli/core_pack/`` so that ``rpgkit init`` works +# cmind-cli ships ``scripts/`` and ``templates/commands/`` as packaged +# assets under ``cmind_cli/core_pack/`` so that ``cmind init`` works # offline. This block exposes: # # _AI_TO_CLI_CMD — single source of truth for "selected AI" → # "AI CLI command to invoke from scripts". # Must stay in sync with the corresponding case # statement in -# ``.github/workflows/scripts/rpgkit/create-release-packages.sh`` +# ``.github/workflows/scripts/cmind/create-release-packages.sh`` # (the release-zip pipeline) and with # ``scripts/common/llm_client.py:_CLI_TO_AGENT`` # (the reverse mapping consumed by detect_agent_type()). # # _SOURCE_BUNDLE / _SOURCE_LEGACY — provisioning channel; persisted as -# ``channel`` in ``~/.rpgkit/workspaces/ +# ``channel`` in ``~/.cmind/workspaces/ # /.meta.toml`` so subsequent -# ``rpgkit update`` calls honour the +# ``cmind update`` calls honour the # user's original choice. Mirrors the -# constants in :mod:`rpgkit_cli._storage`. +# constants in :mod:`cmind_cli._storage`. _AI_TO_CLI_CMD = { # NOTE: values below are copied verbatim from - # .github/workflows/scripts/rpgkit/create-release-packages.sh lines ~142-169 + # .github/workflows/scripts/cmind/create-release-packages.sh lines ~142-169 # to guarantee bundle mode and legacy-download mode behave identically. "copilot": "copilot", "claude": "claude", @@ -360,14 +360,14 @@ def _format_rate_limit_error(status_code: int, headers: httpx.Headers, url: str) } # Re-exported (under the older names) to minimise churn at call sites; -# the canonical strings now live in :mod:`rpgkit_cli._storage`. +# the canonical strings now live in :mod:`cmind_cli._storage`. _SOURCE_BUNDLE = _storage.CHANNEL_BUNDLE _SOURCE_LEGACY = _storage.CHANNEL_LEGACY _CONFIG_RELPATH = _storage.WORKSPACE_MARKER_RELPATH def _current_cli_version() -> str: - """Return the installed ``rpgkit-cli`` version, or ``"dev"`` on failure. + """Return the installed ``cmind-cli`` version, or ``"dev"`` on failure. Used to stamp ``.meta.toml`` with the version that last touched a given workspace. Failures (editable install, missing METADATA, @@ -375,7 +375,7 @@ def _current_cli_version() -> str: field is purely informational. """ try: - return importlib.metadata.version("rpgkit-cli") + return importlib.metadata.version("cmind-cli") except importlib.metadata.PackageNotFoundError: return "dev" @@ -383,7 +383,7 @@ def _current_cli_version() -> str: def _read_source_marker(project_path: Path) -> str | None: """Return the recorded provisioning channel for ``project_path``. - Reads ``channel`` from ``~/.rpgkit/workspaces//.meta.toml``. + Reads ``channel`` from ``~/.cmind/workspaces//.meta.toml``. Returns ``None`` when no meta file exists (fresh workspace) or the channel field is missing. """ @@ -399,21 +399,21 @@ def _read_source_marker(project_path: Path) -> str | None: def _write_source_marker(project_path: Path, source: str) -> None: """Persist the provisioning channel in the home-side ``.meta.toml``. - Replaces the legacy ``workspace/.rpgkit/.source`` text file with a - structured TOML record under ``~/.rpgkit/workspaces//`` that - also carries timestamps and the version of rpgkit-cli that last - touched the workspace. See :mod:`rpgkit_cli._storage` for the + Replaces the legacy ``workspace/.cmind/.source`` text file with a + structured TOML record under ``~/.cmind/workspaces//`` that + also carries timestamps and the version of cmind-cli that last + touched the workspace. See :mod:`cmind_cli._storage` for the layout rationale. """ _storage.write_meta( project_path, channel=source, - rpgkit_cli_version=_current_cli_version(), + cmind_cli_version=_current_cli_version(), ) def _write_workspace_config(project_path: Path, selected_ai: str) -> None: - """Materialise ``.rpgkit/config.toml`` with the selected AI's CLI command. + """Materialise ``.cmind/config.toml`` with the selected AI's CLI command. Idempotent: if the file already exists and already contains ``ai_cli_cmd``, leave it alone (the user may have customised it). @@ -431,27 +431,27 @@ def _write_workspace_config(project_path: Path, selected_ai: str) -> None: cfg_path.parent.mkdir(parents=True, exist_ok=True) cfg_path.write_text( "# CoderMind workspace configuration\n" - "# Managed by `rpgkit init` / `rpgkit update`. Safe to commit.\n" + "# Managed by `cmind init` / `cmind update`. Safe to commit.\n" "# See: https://github.com/microsoft/RPG-ZeroRepo (CoderMind/docs/configuration.md)\n" "\n" - "[rpgkit]\n" + "[cmind]\n" f'ai_cli_cmd = "{cli_cmd}"\n', encoding="utf-8", ) def _detect_install_method() -> str: - """Best-effort detection of how ``rpgkit-cli`` was installed. + """Best-effort detection of how ``cmind-cli`` was installed. Returns one of ``"uv"``, ``"pipx"``, ``"pip-user"``, ``"pip-system"``, - ``"editable"``, ``"unknown"``. Used by ``rpgkit update`` to pick the + ``"editable"``, ``"unknown"``. Used by ``cmind update`` to pick the right self-upgrade command. """ try: # Do not call ``.resolve()`` here. The python # interpreter inside a uv tool venv is typically a symlink to # the system python (``/usr/bin/python3.12`` on Linux); resolving - # it discards the ``~/.local/share/uv/tools/rpgkit-cli/`` prefix + # it discards the ``~/.local/share/uv/tools/cmind-cli/`` prefix # we depend on for installer detection. We want the path *as* # the kernel saw it for ``sys.executable``, not the underlying # interpreter binary it points to. @@ -464,12 +464,12 @@ def _detect_install_method() -> str: # IMPORTANT: editable detection must run FIRST. An editable install # placed inside a uv-managed venv would otherwise be reported as - # "uv" and ``rpgkit update`` would try to upgrade from the + # "uv" and ``cmind update`` would try to upgrade from the # registry instead of leaving the local checkout alone. try: import importlib.metadata as _im - dist = _im.distribution("rpgkit-cli") + dist = _im.distribution("cmind-cli") durl = dist.read_text("direct_url.json") if durl and '"editable": true' in durl: return "editable" @@ -517,18 +517,18 @@ def _upgrade_command(method: str) -> list[str] | None: install, or unknown installer). """ if method == "uv": - return ["uv", "tool", "upgrade", "rpgkit-cli"] + return ["uv", "tool", "upgrade", "cmind-cli"] if method == "pipx": - return ["pipx", "upgrade", "rpgkit-cli"] + return ["pipx", "upgrade", "cmind-cli"] if method == "pip-user": - return [sys.executable, "-m", "pip", "install", "-U", "--user", "rpgkit-cli"] + return [sys.executable, "-m", "pip", "install", "-U", "--user", "cmind-cli"] if method == "pip-system": - return [sys.executable, "-m", "pip", "install", "-U", "rpgkit-cli"] + return [sys.executable, "-m", "pip", "install", "-U", "cmind-cli"] return None def _install_source() -> str: - """Identify *where* the installed ``rpgkit-cli`` came from. + """Identify *where* the installed ``cmind-cli`` came from. Used by the default-on auto-upgrade flow to skip dev-mode installs (local checkout, editable) that the user is actively iterating on — @@ -554,7 +554,7 @@ def _install_source() -> str: """ try: import importlib.metadata as _im - dist = _im.distribution("rpgkit-cli") + dist = _im.distribution("cmind-cli") raw = dist.read_text("direct_url.json") except Exception: return "unknown" @@ -586,7 +586,7 @@ def _install_source() -> str: #: Sources where auto-upgrade is safe to run by default in -#: ``rpgkit update``. Matches the values returned by +#: ``cmind update``. Matches the values returned by #: :func:`_install_source`. _AUTO_UPGRADE_SOURCES: frozenset[str] = frozenset({"git", "pypi"}) @@ -598,9 +598,9 @@ def _install_source() -> str: # absent (greenfield), so we don't impose Python # conventions on an existing repo that already has # its own .gitignore preferences. -# * RPGKIT_COMMON → always injected; these files must be ignored +# * CMIND_COMMON → always injected; these files must be ignored # (runtime data, machine-specific config). -# * RPGKIT_AI[ai] → always injected for the selected AI assistant. +# * CMIND_AI[ai] → always injected for the selected AI assistant. # # The Python template is a verbatim copy of GitHub's official # ``github/gitignore/Python.gitignore`` (220-line community baseline). @@ -835,18 +835,18 @@ def _install_source() -> str: .streamlit/secrets.toml """ -_GITIGNORE_RPGKIT_HEADER = "# RPG-Kit ignores (managed by `rpgkit init/update`)" +_GITIGNORE_CMIND_HEADER = "# CoderMind ignores (managed by `cmind init/update`)" -_GITIGNORE_RPGKIT_COMMON = """\ +_GITIGNORE_CMIND_COMMON = """\ # Runtime workspace (logs, generated data, trajectory) -.rpgkit/ +.cmind/ # but DO track the workspace AI config so collaborators see the same # default — see docs/configuration.md -!.rpgkit/config.toml +!.cmind/config.toml # Codegen dev environments .venv_dev/ -.rpgkit_dev_env/ +.cmind_dev_env/ # Machine-specific config (absolute interpreter paths) .vscode/mcp.json @@ -854,19 +854,19 @@ def _install_source() -> str: .mcp.json """ -# AI-specific slash-command directories that RPG-Kit regenerates each time -# `rpgkit init/update` runs. Each entry covers only a sub-directory of +# AI-specific slash-command directories that CoderMind regenerates each time +# `cmind init/update` runs. Each entry covers only a sub-directory of # the agent folder so unrelated assets in ``.github/`` (workflows, # CODEOWNERS, …) or ``.claude/`` (settings.json with team-shared # permissions) remain trackable. -_GITIGNORE_RPGKIT_AI = { +_GITIGNORE_CMIND_AI = { "copilot": """\ -# Copilot slash command definitions (regenerated by rpgkit) +# Copilot slash command definitions (regenerated by cmind) .github/agents/ .github/prompts/ """, "claude": """\ -# Claude Code slash command definitions (regenerated by rpgkit) +# Claude Code slash command definitions (regenerated by cmind) .claude/commands/ """, } @@ -881,8 +881,7 @@ def _install_source() -> str: """ TAGLINE = ( - "CoderMind — Plan-first coding for Claude Code & GitHub Copilot\n" - "(formerly RPG-Kit — CLI commands rename in a future release)" + "CoderMind — Repository Planning Graphs for AI coding agents" ) @@ -1104,8 +1103,8 @@ def format_help(self, ctx, formatter): app = typer.Typer( - name="rpgkit", - help="Setup tool for CoderMind (formerly RPG-Kit) — repository planning graph workspaces", + name="cmind", + help="Provision and manage Repository Planning Graph (RPG) workspaces for AI coding agents.", add_completion=False, invoke_without_command=True, cls=BannerGroup, @@ -1137,7 +1136,7 @@ def callback(ctx: typer.Context): ): show_banner() console.print( - Align.center("[dim]Run 'rpgkit --help' for usage information[/dim]") + Align.center("[dim]Run 'cmind --help' for usage information[/dim]") ) console.print() @@ -1222,24 +1221,24 @@ def is_git_repo(path: Path = None) -> bool: def _setup_gitignore(project_path: Path, selected_ai: str) -> None: - """Materialize ``.gitignore`` with RPG-Kit's required rules. + """Materialize ``.gitignore`` with CoderMind's required rules. - This is the single injection point for all RPG-Kit gitignore + This is the single injection point for all CoderMind gitignore management. Other init steps (``_generate_mcp_config``, ``_install_copilot_hooks``) must not modify ``.gitignore`` themselves; all rules they used to inject have been folded into - ``_GITIGNORE_RPGKIT_COMMON`` / ``_GITIGNORE_RPGKIT_AI``. + ``_GITIGNORE_CMIND_COMMON`` / ``_GITIGNORE_CMIND_AI``. Behavior: * **Greenfield** — both ``.git/`` and ``.gitignore`` are absent: - write Python standard template + RPG-Kit common + AI-specific + write Python standard template + CoderMind common + AI-specific rules. Gives new projects a complete, sensible default. * **Existing repo or existing ``.gitignore``** — do not overwrite - the user's Python conventions. Only append RPG-Kit rules + the user's Python conventions. Only append CoderMind rules (deduplicated by exact line match) under a single - ``# RPG-Kit ignores`` header. + ``# CoderMind ignores`` header. Args: project_path: Project root that may or may not be a git repo. @@ -1249,25 +1248,25 @@ def _setup_gitignore(project_path: Path, selected_ai: str) -> None: gitignore = project_path / ".gitignore" git_dir = project_path / ".git" - rpgkit_block = _GITIGNORE_RPGKIT_COMMON - ai_rules = _GITIGNORE_RPGKIT_AI.get(selected_ai) + cmind_block = _GITIGNORE_CMIND_COMMON + ai_rules = _GITIGNORE_CMIND_AI.get(selected_ai) if ai_rules: - rpgkit_block += "\n" + ai_rules + cmind_block += "\n" + ai_rules # Greenfield: brand-new project, no git, no existing .gitignore. - # Lay down the full template (Python conventions + RPG-Kit rules). + # Lay down the full template (Python conventions + CoderMind rules). if not git_dir.exists() and not gitignore.exists(): gitignore.write_text( _GITIGNORE_PYTHON_TEMPLATE + "\n" - + _GITIGNORE_RPGKIT_HEADER + + _GITIGNORE_CMIND_HEADER + "\n" - + rpgkit_block, + + cmind_block, encoding="utf-8", ) return - # Brownfield: respect the user's existing setup, only ensure RPG-Kit + # Brownfield: respect the user's existing setup, only ensure CoderMind # rules are present. Parse existing entries (strip whitespace, drop # comments and leading ``/``) so we can compare line-by-line. if gitignore.exists(): @@ -1286,11 +1285,11 @@ def _norm(line: str) -> str: if line.strip() and not line.strip().startswith("#") } - # Collect RPG-Kit pattern lines (skip comments and blanks in the + # Collect CoderMind pattern lines (skip comments and blanks in the # block — comments are kept for the appended section but not used # for dedup checks). missing_lines: list[str] = [] - for line in rpgkit_block.splitlines(): + for line in cmind_block.splitlines(): stripped = line.strip() if not stripped or stripped.startswith("#"): continue @@ -1300,15 +1299,15 @@ def _norm(line: str) -> str: if not missing_lines: return - # Append under a single, idempotent RPG-Kit header so repeated runs + # Append under a single, idempotent CoderMind header so repeated runs # don't create duplicate section markers. parts: list[str] = [] if existing_text and not existing_text.endswith("\n"): parts.append("\n") if existing_text: parts.append("\n") - if _GITIGNORE_RPGKIT_HEADER not in existing_text: - parts.append(_GITIGNORE_RPGKIT_HEADER + "\n") + if _GITIGNORE_CMIND_HEADER not in existing_text: + parts.append(_GITIGNORE_CMIND_HEADER + "\n") parts.extend(line + "\n" for line in missing_lines) with open(gitignore, "a", encoding="utf-8") as f: @@ -1465,10 +1464,10 @@ def _load_json_dict(path: Path) -> dict: def _cleanup_legacy_vscode_mcp(project_path: Path) -> None: """Remove a stale ``mcp.servers.rpg-tools`` entry from ``.vscode/settings.json``. - Earlier versions of ``rpgkit init`` registered the MCP server inside + Earlier versions of ``cmind init`` registered the MCP server inside ``settings.json``. We've since moved to ``.vscode/mcp.json``; this helper deletes only the stale entry so users upgrading via - ``rpgkit update`` don't end up with two registrations. + ``cmind update`` don't end up with two registrations. Other settings — and any non-rpg-tools MCP servers the user may have added — are preserved untouched. @@ -1500,21 +1499,21 @@ def _cleanup_legacy_vscode_mcp(project_path: Path) -> None: def _cleanup_legacy_codegen_persistent(project_path: Path) -> list[str]: - """Delete obsolete ``rpgkit-codegen.*`` persistent-instruction files. + """Delete obsolete ``cmind-codegen.*`` persistent-instruction files. - Earlier versions of ``rpgkit init`` (pre-C4 cleanup) wrote a + Earlier versions of ``cmind init`` (pre-C4 cleanup) wrote a codegen-specific instructions file that AI agents would auto-load on every session, polluting unrelated commands (rpg_edit, encode, plain Q&A) with codegen workflow noise. This helper: - * Removes ``/.claude/rules/rpgkit-codegen.md`` - * Removes ``/.github/instructions/rpgkit-codegen.instructions.md`` + * Removes ``/.claude/rules/cmind-codegen.md`` + * Removes ``/.github/instructions/cmind-codegen.instructions.md`` * Also cleans the legacy ``/repo/.claude/...`` and ``/repo/.github/...`` paths, so workspaces created under the old ``/repo`` layout are upgraded on the - next ``rpgkit init`` / ``rpgkit update`` run. + next ``cmind init`` / ``cmind update`` run. * Tidies up empty parent directories the file leaves behind. * Returns the list of paths actually removed (for tracker reporting). @@ -1524,12 +1523,12 @@ def _cleanup_legacy_codegen_persistent(project_path: Path) -> list[str]: legacy_repo_dir = project_path / "repo" candidates = [ # New layout (workspace == repo) - project_path / ".claude" / "rules" / "rpgkit-codegen.md", - project_path / ".github" / "instructions" / "rpgkit-codegen.instructions.md", + project_path / ".claude" / "rules" / "cmind-codegen.md", + project_path / ".github" / "instructions" / "cmind-codegen.instructions.md", # Legacy layout (/repo) — keep scanning so users who # upgrade from old workspaces still get the file removed. - legacy_repo_dir / ".claude" / "rules" / "rpgkit-codegen.md", - legacy_repo_dir / ".github" / "instructions" / "rpgkit-codegen.instructions.md", + legacy_repo_dir / ".claude" / "rules" / "cmind-codegen.md", + legacy_repo_dir / ".github" / "instructions" / "cmind-codegen.instructions.md", ] removed: list[str] = [] @@ -1562,7 +1561,7 @@ def _generate_mcp_config( """Generate MCP server configuration for the selected AI assistant. Both Claude and VS Code Copilot launch the MCP server via the - ``rpgkit-mcp`` console script installed alongside ``rpgkit-cli``. + ``cmind-mcp`` console script installed alongside ``cmind-cli``. This keeps the config portable across machines (no absolute paths to a workspace-local copy) and ensures the server always runs against the bundled scripts that match the installed CLI version. @@ -1571,7 +1570,7 @@ def _generate_mcp_config( - Copilot: ``.vscode/mcp.json`` (key ``servers.rpg-tools``, VS Code 1.102+ standard layout) - The ``rpgkit-mcp`` command must be on ``PATH``. ``rpgkit init`` + The ``cmind-mcp`` command must be on ``PATH``. ``cmind init`` emits a warning at the end of the run when it isn't, so MCP clients fail with a clear cause rather than the opaque ``Connection closed`` error. @@ -1579,7 +1578,7 @@ def _generate_mcp_config( project_path = project_path.resolve() mcp_server_config = { - "command": "rpgkit-mcp", + "command": "cmind-mcp", "args": [], } @@ -1649,20 +1648,20 @@ def _register_copilot_cli_global_mcp(tracker=None) -> None: inline JSON via ``--additional-mcp-config``). To make ``copilot`` find ``rpg-tools`` automatically in any - rpgkit-initialised workspace, we register the server globally on - first ``rpgkit init --ai copilot`` (or ``rpgkit update``). + cmind-initialised workspace, we register the server globally on + first ``cmind init --ai copilot`` (or ``cmind update``). - This is safe because ``rpgkit-mcp`` is cwd-aware (it walks up to + This is safe because ``cmind-mcp`` is cwd-aware (it walks up to find ``rpg.json``) and stateless across workspaces — one global registration serves every workspace the user ``cd``-s into. In workspaces without ``rpg.json`` the server starts in degraded mode and tool calls return a ``rpg_unavailable`` hint instructing the - user to run ``/rpgkit.encode``. + user to run ``/cmind.encode``. Safety rules (see audit decisions D-globalmcp-1..4): - **No-op when in-sync.** If the file already contains exactly the entry we'd write, we don't touch it at all (no mtime bump, - no .bak). This makes ``rpgkit update`` cheap to run repeatedly. + no .bak). This makes ``cmind update`` cheap to run repeatedly. - **Refuse to wipe a malformed config.** If the file exists but isn't valid JSON we abort with a clear error instead of overwriting; the user is expected to fix it (or run with @@ -1684,7 +1683,7 @@ def _register_copilot_cli_global_mcp(tracker=None) -> None: tmp_path = config_path.with_suffix(".json.tmp") desired = { "type": "stdio", - "command": "rpgkit-mcp", + "command": "cmind-mcp", "args": [], } @@ -1755,13 +1754,13 @@ def _report_done(detail: str) -> None: return # Respect a user-customised entry — only touch entries that - # either don't exist or already point at our `rpgkit-mcp` + # either don't exist or already point at our `cmind-mcp` # console script (the latter happens on a version bump where # we'd want to e.g. add new default args). if ( isinstance(current, dict) and current.get("command") - and current.get("command") != "rpgkit-mcp" + and current.get("command") != "cmind-mcp" ): _report_skip( f"existing entry uses custom command " @@ -1807,20 +1806,20 @@ def _report_done(detail: str) -> None: # --------------------------------------------------------------------------- def _workspace_has_python_code(project_path: Path) -> bool: - """Return True if the workspace contains any ``*.py`` file outside ``.rpgkit/``. + """Return True if the workspace contains any ``*.py`` file outside ``.cmind/``. - Used to decide whether ``rpgkit init`` should offer to build the RPG + Used to decide whether ``cmind init`` should offer to build the RPG immediately. Greenfield workspaces (or repos that don't ship Python code) skip the prompt because the encoder would produce an empty graph and waste LLM tokens. - The walk prunes the ``.rpgkit`` directory in-place so workspace + The walk prunes the ``.cmind`` directory in-place so workspace runtime state (``data/``, ``logs/``) doesn't influence the detection. Common boilerplate dirs (``.git``, ``.venv``, ``node_modules``, ``__pycache__``) are pruned too — a ``*.py`` under any of them would not indicate user code. """ - PRUNE = {".rpgkit", ".git", ".venv", "venv", "node_modules", + PRUNE = {".cmind", ".git", ".venv", "venv", "node_modules", "__pycache__", ".tox", ".mypy_cache", ".pytest_cache", ".ruff_cache", "dist", "build"} for dirpath, dirnames, filenames in os.walk(project_path): @@ -1979,7 +1978,7 @@ def _run_initial_encode(project_path: Path) -> bool: of lines of ``RPGParser - INFO - ...``), so instead we: * Capture stderr in a reader thread and write it verbatim to - ``~/.rpgkit/workspaces//logs/encode.log`` — power users + ``~/.cmind/workspaces//logs/encode.log`` — power users can ``tail -f`` it for the full firehose. * Parse a handful of phase markers off each line to drive a :class:`rich.progress.Progress` bar with a spinner + current @@ -1988,16 +1987,16 @@ def _run_initial_encode(project_path: Path) -> bool: failure so the user has something concrete to debug. Returns True on success (exit code 0), False otherwise. Never - raises: ``rpgkit init`` itself has already succeeded by the time we + raises: ``cmind init`` itself has already succeeded by the time we get here and we don't want a flaky LLM call to make the whole command look like it failed. """ - encoder = project_path / ".rpgkit" / "scripts" / "rpg_encoder" / "run_encode.py" + encoder = project_path / ".cmind" / "scripts" / "rpg_encoder" / "run_encode.py" if not encoder.is_file(): # Scripts live inside the installed wheel under - # ``rpgkit_cli/core_pack/scripts/``. Resolve the encoder + # ``cmind_cli/core_pack/scripts/``. Resolve the encoder # from there so the optional initial-encode kickoff works after - # ``rpgkit init`` — which no longer copies scripts into the + # ``cmind init`` — which no longer copies scripts into the # workspace. from . import _assets candidate = _assets.scripts_dir() / "rpg_encoder" / "run_encode.py" @@ -2006,13 +2005,13 @@ def _run_initial_encode(project_path: Path) -> bool: else: console.print( f"[yellow]Encoder script not found at {candidate}; " - f"run [cyan]/rpgkit.encode[/] in your AI agent later.[/yellow]" + f"run [cyan]/cmind.encode[/] in your AI agent later.[/yellow]" ) return False # Keep all generated artefacts (logs/data/inner-git) in the - # per-workspace home dir under ~/.rpgkit/workspaces//. The - # workspace tree should stay clean — no .rpgkit/logs/ written here. + # per-workspace home dir under ~/.cmind/workspaces//. The + # workspace tree should stay clean — no .cmind/logs/ written here. from . import _storage log_dir = _storage.workspace_logs_dir(project_path) try: @@ -2029,7 +2028,7 @@ def _run_initial_encode(project_path: Path) -> bool: "Building [cyan]rpg.json[/] from your code via the LLM. " "Verbose logs stream to [cyan]" + str(log_path) + "[/] — " "`tail -f` it in another terminal for the gory details. " - "Press Ctrl-C to abort; re-run later with [cyan]/rpgkit.encode[/].", + "Press Ctrl-C to abort; re-run later with [cyan]/cmind.encode[/].", title="[bold]Initial encode[/bold]", border_style="cyan", padding=(1, 2), @@ -2215,7 +2214,7 @@ def _stderr_reader() -> None: if interrupted: console.print( "\n[yellow]Encoder interrupted. Re-run later with " - "[cyan]/rpgkit.encode[/].[/yellow]" + "[cyan]/cmind.encode[/].[/yellow]" ) return False @@ -2248,7 +2247,7 @@ def _stderr_reader() -> None: Panel( f"[red]Encoder exited with code {proc.returncode}.[/]\n\n" f"Check [cyan]{log_path}[/] for the full log. You can retry " - "with [cyan]/rpgkit.encode[/] after fixing the issue." + "with [cyan]/cmind.encode[/] after fixing the issue." f"{summary_blurb}", title="[bold red]Encode failed[/bold red]", border_style="red", @@ -2274,11 +2273,11 @@ def _maybe_offer_initial_encode( hasn't been built before. Defaults to "No" so an accidental Enter doesn't kick off a long LLM job. - Failures never propagate — ``rpgkit init`` is already done and we + Failures never propagate — ``cmind init`` is already done and we don't want a flaky encoder to taint the exit code. """ # Already encoded: nothing to do. - rpg_file = project_path / ".rpgkit" / "data" / "rpg.json" + rpg_file = project_path / ".cmind" / "data" / "rpg.json" if rpg_file.exists(): return @@ -2297,11 +2296,11 @@ def _maybe_offer_initial_encode( Panel( "CoderMind can build the initial graph for this repo now by " "running the encoder against your existing code. This is " - "what the [cyan]/rpgkit.encode[/] slash command does — kicking " + "what the [cyan]/cmind.encode[/] slash command does — kicking " "it off here saves you a step.\n\n" "[yellow]Heads up:[/] the encoder calls an LLM and can take " "a few minutes on a real-sized repo. You can always say " - "No and run [cyan]/rpgkit.encode[/] in your AI agent later.", + "No and run [cyan]/cmind.encode[/] in your AI agent later.", title="[bold]Build the RPG now?[/bold]", border_style="cyan", padding=(1, 2), @@ -2324,9 +2323,9 @@ def _install_claude_hooks(project_path: Path) -> None: Merges with existing hooks/permissions without overwriting user-defined entries. A backup of the original file is created before any modification. Idempotent across Python interpreter - upgrades and repeated ``rpgkit init/update`` runs: + upgrades and repeated ``cmind init/update`` runs: - * Any prior RPG-Kit SessionStart entry (identified by the + * Any prior CoderMind SessionStart entry (identified by the ``update_graphs.py`` marker in its command) is replaced rather than duplicated. * The ``mcp__rpg-tools`` allow rule is added only if absent. @@ -2334,7 +2333,7 @@ def _install_claude_hooks(project_path: Path) -> None: Why pre-authorize ``mcp__rpg-tools``? Claude Code prompts the user before each MCP tool invocation unless the rule is present in ``permissions.allow``. Since - the RPG-Kit server only exposes four read-only graph-query + the CoderMind server only exposes four read-only graph-query tools (``search_rpg``, ``explore_rpg``, ``get_node_detail``, ``list_rpg_tree``) that touch no external state, requiring confirmation for every call is pure friction. The @@ -2350,7 +2349,7 @@ def _install_claude_hooks(project_path: Path) -> None: # The command is executed by Claude Code via ``sh -c``, so we inline # the same PATH-fallback used by git hooks (see _HOOK_PATH_FALLBACK). - # Use ``;`` rather than ``&&`` so the rpgkit call always runs after + # Use ``;`` rather than ``&&`` so the cmind call always runs after # the (possibly no-op) PATH adjustment. marker = "update_graphs.py" # used for idempotent dedupe across upgrades @@ -2361,7 +2360,7 @@ def _install_claude_hooks(project_path: Path) -> None: "type": "command", "command": ( f"{_HOOK_PATH_FALLBACK}; " - "rpgkit script update_graphs.py status 2>/dev/null" + "cmind script update_graphs.py status 2>/dev/null" " || echo '[CoderMind] RPG status unavailable'" ), "timeout": 10, @@ -2378,11 +2377,11 @@ def _install_claude_hooks(project_path: Path) -> None: if not isinstance(session_start, list): session_start = [] - def _is_rpgkit_entry(entry: object) -> bool: - """Detect a previously-installed RPG-Kit SessionStart entry. + def _is_cmind_entry(entry: object) -> bool: + """Detect a previously-installed CoderMind SessionStart entry. Matches both the current (shlex-quoted) and earlier - (json.dumps-quoted) command shapes, plus any custom RPG-Kit + (json.dumps-quoted) command shapes, plus any custom CoderMind entry the user may have added that still calls update_graphs.py. """ if not isinstance(entry, dict): @@ -2393,8 +2392,8 @@ def _is_rpgkit_entry(entry: object) -> bool: return True return False - # Drop any stale RPG-Kit entry before appending the fresh one. - session_start = [e for e in session_start if not _is_rpgkit_entry(e)] + # Drop any stale CoderMind entry before appending the fresh one. + session_start = [e for e in session_start if not _is_cmind_entry(e)] session_start.append(rpg_session_entry) merged["SessionStart"] = session_start @@ -2411,9 +2410,9 @@ def _is_rpgkit_entry(entry: object) -> bool: allow = permissions.get("allow") if not isinstance(allow, list): allow = [] - rpgkit_rule = "mcp__rpg-tools" - if rpgkit_rule not in allow: - allow.append(rpgkit_rule) + cmind_rule = "mcp__rpg-tools" + if cmind_rule not in allow: + allow.append(cmind_rule) permissions["allow"] = allow existing["permissions"] = permissions @@ -2436,7 +2435,7 @@ def _read_core_hooks_path(project_path: Path) -> Optional[Path]: Why this matters: teams using ``pre-commit``, ``husky``, ``lefthook`` and similar hook frameworks routinely override ``core.hooksPath`` to point at a checked-in directory (e.g. ``.husky/``). Without this - lookup, ``rpgkit init`` would write into ``.git/hooks/`` where git + lookup, ``cmind init`` would write into ``.git/hooks/`` where git never reads from, leaving the user with a silent no-op install. """ try: @@ -2518,7 +2517,7 @@ def _resolve_git_hooks_dir(project_path: Path) -> Optional[Path]: return None -# Each entry describes one shape of legacy (pre-sentinel) RPG-Kit snippet +# Each entry describes one shape of legacy (pre-sentinel) CoderMind snippet # that may exist in a user's hook file from an older release. The first # element is a substring of the snippet's first line (a marker comment); # the second is the *total* number of consecutive lines that snippet @@ -2533,15 +2532,15 @@ def _strip_hook_block( block_name: str, legacy_blocks: Tuple[LegacyBlock, ...] = (), ) -> str: - """Return ``text`` with any RPG-Kit-owned hook content removed. + """Return ``text`` with any CoderMind-owned hook content removed. Two cleanup passes: 1. Strip the new-style sentinel block:: - # RPGKIT-BEGIN + # CMIND-BEGIN ... - # RPGKIT-END + # CMIND-END Range-based, so multi-line bodies of any shape are atomically removed in one shot. @@ -2555,8 +2554,8 @@ def _strip_hook_block( Lines outside both passes are preserved verbatim so user-authored hook content (and shebangs) survive untouched. """ - begin_sent = f"# RPGKIT-BEGIN {block_name}" - end_sent = f"# RPGKIT-END {block_name}" + begin_sent = f"# CMIND-BEGIN {block_name}" + end_sent = f"# CMIND-END {block_name}" lines = text.splitlines() # Pass 1: strip sentinel block (matching pair). @@ -2599,19 +2598,19 @@ def _strip_hook_block( # PATH fallback for hook bodies # --------------------------------------------------------------------------- # -# Hooks invoke ``rpgkit`` (the globally-installed CLI) rather than a +# Hooks invoke ``cmind`` (the globally-installed CLI) rather than a # workspace-local script copy. When the hook is triggered from a GUI # editor's source-control panel (VS Code, IntelliJ, GitHub Desktop, ...) # the process environment may not include the user's shell PATH, so -# ``rpgkit`` is unresolvable and the hook silently fails. +# ``cmind`` is unresolvable and the hook silently fails. # -# This snippet is prepended to every hook body. When ``rpgkit`` is +# This snippet is prepended to every hook body. When ``cmind`` is # already on PATH (terminal invocations) the test short-circuits and # the ``export`` is skipped — zero overhead. When it isn't, we # prepend ``$HOME/.local/bin`` which is ``uv tool install``'s default # bin directory. _HOOK_PATH_FALLBACK = ( - 'command -v rpgkit >/dev/null 2>&1 || ' + 'command -v cmind >/dev/null 2>&1 || ' 'export PATH="$HOME/.local/bin:$PATH"' ) @@ -2624,19 +2623,19 @@ def _install_hook_snippet( *, legacy_blocks: Tuple[LegacyBlock, ...] = (), ) -> bool: - """Install or replace an RPG-Kit-owned block in ``/``. + """Install or replace an CoderMind-owned block in ``/``. File layout written:: #!/bin/sh - # RPGKIT-BEGIN + # CMIND-BEGIN - # RPGKIT-END + # CMIND-END - The block is **atomically replaceable**: subsequent ``rpgkit init`` / - ``rpgkit update`` runs find the existing sentinels and replace the + The block is **atomically replaceable**: subsequent ``cmind init`` / + ``cmind update`` runs find the existing sentinels and replace the whole block, so behavior upgrades land cleanly without piling new snippets on top of old ones. ``legacy_blocks`` is used **once** to migrate pre-sentinel installs (released through v0.0.99-dev.72) onto @@ -2663,8 +2662,8 @@ def _install_hook_snippet( else: prefix = "#!/bin/sh\n" + cleaned + "\n" - begin = f"# RPGKIT-BEGIN {block_name}" - end = f"# RPGKIT-END {block_name}" + begin = f"# CMIND-BEGIN {block_name}" + end = f"# CMIND-END {block_name}" block = f"\n{begin}\n{body.rstrip()}\n{end}\n" hook_path.write_text(prefix + block, encoding="utf-8") @@ -2673,13 +2672,13 @@ def _install_hook_snippet( def _uninstall_git_pre_commit_hook(project_path: Path) -> bool: - """Remove any previously-installed RPG-Kit ``pre-commit`` block. + """Remove any previously-installed CoderMind ``pre-commit`` block. Pre-commit was retired in favour of ``post-commit`` only: the pre-commit sync ran ``--staged-only`` and was immediately followed by the full post-commit sync, so its output had a ~1 sec lifetime and added latency to every ``git commit`` for no observable benefit. - Existing workspaces upgraded via ``rpgkit init`` / ``rpgkit update`` + Existing workspaces upgraded via ``cmind init`` / ``cmind update`` have their pre-commit block stripped here; user-authored hook content (and other tools' blocks such as husky / pre-commit / lefthook) is preserved untouched. @@ -2697,9 +2696,9 @@ def _uninstall_git_pre_commit_hook(project_path: Path) -> bool: existing = hook_path.read_text(encoding="utf-8") legacy = ( - ("# RPG-Kit: pre-commit dispatcher", 3), - ("# RPG-Kit: full RPG sync on commit", 2), - ("# RPG-Kit: incremental RPG sync on commit", 3), + ("# CoderMind: pre-commit dispatcher", 3), + ("# CoderMind: full RPG sync on commit", 2), + ("# CoderMind: incremental RPG sync on commit", 3), ) cleaned = _strip_hook_block(existing, "pre-commit", legacy).rstrip("\n") @@ -2732,12 +2731,12 @@ def _install_git_post_merge_hook(project_path: Path) -> bool: if hooks_dir is None: return False - # Level-1 hook: stub delegates to ``rpgkit hook post-merge``. - marker = "# RPG-Kit: post-merge dispatcher" + # Level-1 hook: stub delegates to ``cmind hook post-merge``. + marker = "# CoderMind: post-merge dispatcher" body = ( f"{marker}\n" f"{_HOOK_PATH_FALLBACK}\n" - f"rpgkit hook post-merge 2>/dev/null || true" + f"cmind hook post-merge 2>/dev/null || true" ) return _install_hook_snippet( hooks_dir, @@ -2745,7 +2744,7 @@ def _install_git_post_merge_hook(project_path: Path) -> bool: "post-merge", body, legacy_blocks=( - ("# RPG-Kit: incremental RPG sync after merge / pull", 3), + ("# CoderMind: incremental RPG sync after merge / pull", 3), ), ) @@ -2754,20 +2753,20 @@ def _install_git_post_commit_hook(project_path: Path) -> bool: """Install the Level-1 ``post-commit`` dispatcher stub. The on-disk hook is now a 3-line shell snippet that ``exec``s - ``rpgkit hook post-commit``. All orchestration lives in the + ``cmind hook post-commit``. All orchestration lives in the :func:`hook` Python command: * **Phase 1 (foreground)**: ``update_graphs.py sync`` advances ``meta.git`` to the new HEAD. Output is teed into - ``~/.rpgkit/workspaces//logs/hooks.log``. + ``~/.cmind/workspaces//logs/hooks.log``. * **Phase 2 (background)**: ``update_graphs.py update-rpg`` is detached via ``subprocess.Popen(start_new_session=True)``. A mkdir-based directory lock at - ``~/.rpgkit/workspaces//logs/.update_rpg.lock`` serialises + ``~/.cmind/workspaces//logs/.update_rpg.lock`` serialises overlapping commits; locks older than 60 minutes are treated as orphaned and removed. The worker's stdout/stderr land in - ``~/.rpgkit/workspaces//logs/update_rpg.log``. + ``~/.cmind/workspaces//logs/update_rpg.log``. Both phases are best-effort: every failure path is swallowed inside :func:`hook` so a hook misbehaviour never blocks ``git commit``. @@ -2780,11 +2779,11 @@ def _install_git_post_commit_hook(project_path: Path) -> bool: if hooks_dir is None: return False - marker = "# RPG-Kit: post-commit dispatcher" + marker = "# CoderMind: post-commit dispatcher" body = ( f"{marker}\n" f"{_HOOK_PATH_FALLBACK}\n" - f"rpgkit hook post-commit 2>/dev/null || true" + f"cmind hook post-commit 2>/dev/null || true" ) return _install_hook_snippet( hooks_dir, @@ -2793,11 +2792,11 @@ def _install_git_post_commit_hook(project_path: Path) -> bool: body, legacy_blocks=( # v1 (pre-Step-3): two-line sync-only snippet. - ("# RPG-Kit: advance meta.git after commit", 2), + ("# CoderMind: advance meta.git after commit", 2), # v3 (release 0576393): five-line snippet with phase-1 sync # + phase-2 setsid background under the same marker we used # before Level-1. - ("# RPG-Kit: advance meta.git + background feature graph update", 5), + ("# CoderMind: advance meta.git + background feature graph update", 5), ), ) @@ -2830,13 +2829,13 @@ def _install_copilot_hooks(project_path: Path) -> None: pass rpg_status_task = { - "label": "RPG-Kit: load status", + "label": "CoderMind: load status", "type": "shell", # Invoke the globally-installed CLI rather than a workspace # script copy (which no longer exists). Same # rationale as the git-hook bodies: portable command name, # auto-tracks the installed wheel's scripts. - "command": "rpgkit", + "command": "cmind", "args": ["script", "update_graphs.py", "status"], "presentation": { "echo": False, @@ -2850,7 +2849,7 @@ def _install_copilot_hooks(project_path: Path) -> None: "runOptions": {"runOn": "folderOpen"}, "problemMatcher": [], "detail": ( - "Prints RPG-Kit status and rpg-tools MCP usage guidance " + "Prints CoderMind status and rpg-tools MCP usage guidance " "so GitHub Copilot can locate and generate code against " "the Repository Program Graph." ), @@ -2861,8 +2860,8 @@ def _install_copilot_hooks(project_path: Path) -> None: if not isinstance(tasks_list, list): tasks_list = [] - # Replace any prior RPG-Kit task with the same label rather than - # appending duplicates on repeated ``rpgkit update`` runs. + # Replace any prior CoderMind task with the same label rather than + # appending duplicates on repeated ``cmind update`` runs. label = rpg_status_task["label"] tasks_list = [t for t in tasks_list if not (isinstance(t, dict) and t.get("label") == label)] tasks_list.append(rpg_status_task) @@ -2987,27 +2986,27 @@ def _release_sort_key(release: dict) -> str: return release.get("published_at") or release.get("created_at") or "" -def _select_latest_rpgkit_release(releases: List[dict], *, pre: bool) -> dict | None: +def _select_latest_cmind_release(releases: List[dict], *, pre: bool) -> dict | None: candidates = [ release for release in releases if not release.get("draft") and release.get("prerelease", False) is pre - and release.get("tag_name", "").startswith(_RPGKIT_RELEASE_TAG_PREFIX) + and release.get("tag_name", "").startswith(_CMIND_RELEASE_TAG_PREFIX) ] candidates.sort(key=_release_sort_key, reverse=True) return candidates[0] if candidates else None -def _format_rpgkit_version(tag_name: str) -> str: - if tag_name.startswith(_RPGKIT_RELEASE_TAG_PREFIX): - return tag_name[len(_RPGKIT_RELEASE_TAG_PREFIX) :] +def _format_cmind_version(tag_name: str) -> str: + if tag_name.startswith(_CMIND_RELEASE_TAG_PREFIX): + return tag_name[len(_CMIND_RELEASE_TAG_PREFIX) :] if tag_name.startswith("v"): return tag_name[1:] return tag_name -def _fetch_latest_rpgkit_release( +def _fetch_latest_cmind_release( repo_owner: str, repo_name: str, client: httpx.Client, @@ -3041,12 +3040,12 @@ def _fetch_latest_rpgkit_release( if not isinstance(releases, list): raise RuntimeError("Unexpected response format when fetching releases list.") - release_data = _select_latest_rpgkit_release(releases, pre=pre) + release_data = _select_latest_cmind_release(releases, pre=pre) if release_data is None: release_type = "pre-release" if pre else "release" raise RuntimeError( f"No CoderMind {release_type} found in {repo_owner}/{repo_name}. " - f"Expected tags to start with {_RPGKIT_RELEASE_TAG_PREFIX}." + f"Expected tags to start with {_CMIND_RELEASE_TAG_PREFIX}." ) return release_data @@ -3081,7 +3080,7 @@ def download_template_from_github( console.print("[cyan]Fetching latest release information...[/cyan]") try: - release_data = _fetch_latest_rpgkit_release( + release_data = _fetch_latest_cmind_release( repo_owner, repo_name, client, @@ -3096,7 +3095,7 @@ def download_template_from_github( raise typer.Exit(1) assets = release_data.get("assets", []) - pattern = f"rpgkit-template-{ai_assistant}-{script_type}" + pattern = f"cmind-template-{ai_assistant}-{script_type}" matching_assets = [ asset for asset in assets @@ -3212,9 +3211,9 @@ def download_and_extract_template( """Provision the workspace with scripts + command templates. Bundle-only as of v0.1.4: templates are always sourced from the - packaged assets shipped inside ``rpgkit_cli/core_pack/``. To pick + packaged assets shipped inside ``cmind_cli/core_pack/``. To pick up newer prompts the user upgrades the CLI itself (``uv tool - upgrade rpgkit-cli`` etc.), which ``rpgkit update`` does + upgrade cmind-cli`` etc.), which ``cmind update`` does automatically by default. The ``github_token`` / ``pre`` / ``legacy_download`` parameters and @@ -3247,9 +3246,9 @@ def _install_from_bundle( """Materialise per-AI command templates into the workspace. The pipeline scripts themselves live inside the installed wheel at - ``rpgkit_cli/core_pack/scripts/`` and are invoked via ``rpgkit - script `` (and ``rpgkit-mcp`` for the MCP server) — they are - NOT copied to ``/.rpgkit/scripts/`` anymore. This gives + ``cmind_cli/core_pack/scripts/`` and are invoked via ``cmind + script `` (and ``cmind-mcp`` for the MCP server) — they are + NOT copied to ``/.cmind/scripts/`` anymore. This gives one source of truth per CLI install, no risk of workspace/wheel drift, and no per-workspace scripts dir to keep in sync. @@ -3274,8 +3273,8 @@ def _install_from_bundle( tracker.start("extract") try: - rpgkit_root = project_path / ".rpgkit" - rpgkit_root.mkdir(parents=True, exist_ok=True) + cmind_root = project_path / ".cmind" + cmind_root.mkdir(parents=True, exist_ok=True) # 1. Materialise slash-command templates into the AI-specific # directory. _materialise_commands_for_agent owns the @@ -3284,7 +3283,7 @@ def _install_from_bundle( ai_assistant, _assets.commands_dir(), project_path ) - # 2. Record the provisioning source so subsequent ``rpgkit update`` + # 2. Record the provisioning source so subsequent ``cmind update`` # invocations default to the same channel. _write_source_marker(project_path, _SOURCE_BUNDLE) @@ -3311,18 +3310,18 @@ def _materialise_commands_for_agent( """Place command templates into the agent-specific workspace location. This intentionally mirrors what the legacy release-zip path produces - (see ``.github/workflows/scripts/rpgkit/create-release-packages.sh`` + (see ``.github/workflows/scripts/cmind/create-release-packages.sh`` ``generate_commands`` / ``generate_copilot_prompts``), so that downstream consumers see the same layout regardless of provisioning source. Layout produced: - claude → ``.claude/commands/rpgkit..md`` - copilot → ``.github/agents/rpgkit..agent.md`` - ``.github/prompts/rpgkit..prompt.md`` (frontmatter + claude → ``.claude/commands/cmind..md`` + copilot → ``.github/agents/cmind..agent.md`` + ``.github/prompts/cmind..prompt.md`` (frontmatter points at the corresponding agent) - others → fallback: ``.rpgkit/commands/rpgkit..md`` (same - ``rpgkit..md`` prefix for consistency with the + others → fallback: ``.cmind/commands/cmind..md`` (same + ``cmind..md`` prefix for consistency with the supported agents above) NOTE: ``claude`` and ``copilot`` are the only verified agents in @@ -3336,7 +3335,7 @@ def _read_body(src: Path) -> str: dest = project_path / ".claude" / "commands" dest.mkdir(parents=True, exist_ok=True) for src in src_commands_dir.glob("*.md"): - target = dest / f"rpgkit.{src.stem}.md" + target = dest / f"cmind.{src.stem}.md" target.write_text(_read_body(src), encoding="utf-8") elif ai_assistant == "copilot": agents = project_path / ".github" / "agents" @@ -3344,7 +3343,7 @@ def _read_body(src: Path) -> str: agents.mkdir(parents=True, exist_ok=True) prompts.mkdir(parents=True, exist_ok=True) for src in src_commands_dir.glob("*.md"): - stem = f"rpgkit.{src.stem}" + stem = f"cmind.{src.stem}" body = _read_body(src) (agents / f"{stem}.agent.md").write_text(body, encoding="utf-8") # Copilot prompt files reference the agent by name in @@ -3357,10 +3356,10 @@ def _read_body(src: Path) -> str: # Unknown agent (init() validates against AGENT_CONFIG so this # branch is unreachable from the public CLI, but provides a # well-defined behaviour if a future caller bypasses validation). - dest = project_path / ".rpgkit" / "commands" + dest = project_path / ".cmind" / "commands" dest.mkdir(parents=True, exist_ok=True) for src in src_commands_dir.glob("*.md"): - (dest / f"rpgkit.{src.stem}.md").write_text(_read_body(src), encoding="utf-8") + (dest / f"cmind.{src.stem}.md").write_text(_read_body(src), encoding="utf-8") # DEPRECATED: legacy release-zip provisioning path — no longer reachable @@ -3383,7 +3382,7 @@ def _download_and_extract_release_zip( Kept available for users that need the very latest prompts before the next CLI release, or to bypass packaging glitches. Activated via - ``rpgkit init --legacy-download``. + ``cmind init --legacy-download``. """ current_dir = Path.cwd() @@ -3564,51 +3563,51 @@ def _download_and_extract_release_zip( elif verbose: console.print(f"Cleaned up: {zip_path.name}") - # Record provisioning source so a later ``rpgkit update`` defaults + # Record provisioning source so a later ``cmind update`` defaults # to the same channel. Counterpart to ``_install_from_bundle`` which # writes ``bundle``. _write_source_marker(project_path, _SOURCE_LEGACY) # Discard the scripts copy extracted from the zip — they're not - # used at runtime anymore (the workspace invokes ``rpgkit script + # used at runtime anymore (the workspace invokes ``cmind script # `` which resolves to the packaged scripts dir). Keeping # them would just be dead weight that drifts vs the installed CLI. # Legacy zip contributes commands only. - legacy_scripts_dir = project_path / ".rpgkit" / "scripts" + legacy_scripts_dir = project_path / ".cmind" / "scripts" if legacy_scripts_dir.is_dir(): shutil.rmtree(legacy_scripts_dir, ignore_errors=True) return project_path -def ensure_rpgkit_runtime_dirs( +def ensure_cmind_runtime_dirs( project_path: Path, tracker: StepTracker | None = None ) -> None: - """Pre-create RPG-Kit runtime directories under ``~/.rpgkit/``. + """Pre-create CoderMind runtime directories under ``~/.cmind/``. The per-workspace data, logs, and inner-git snapshot repo live - under the user's home directory at ``~/.rpgkit/workspaces//`` + under the user's home directory at ``~/.cmind/workspaces//`` rather than inside the workspace. Reports stay in the workspace - (``/.rpgkit/reports/``) because they're user-facing + (``/.cmind/reports/``) because they're user-facing artefacts. This function is the central bootstrap for the home layout: it's - idempotent and safe to call from both ``rpgkit init`` (when the - channel was just chosen) and ``rpgkit update`` (when the channel + idempotent and safe to call from both ``cmind init`` (when the + channel was just chosen) and ``cmind update`` (when the channel is read from the existing meta file). Some early-pipeline prompts redirect stdout/stderr to ``/.log`` via shell ``>`` before any Python code runs, so we must create the directories upfront rather than lazily. Created (idempotent): - - ``~/.rpgkit/workspaces//data/`` - - ``~/.rpgkit/workspaces//data/trajectory/`` - - ``~/.rpgkit/workspaces//logs/`` - - ``/.rpgkit/reports/`` - - ``~/.rpgkit/workspaces//.meta.toml`` (refreshed) + - ``~/.cmind/workspaces//data/`` + - ``~/.cmind/workspaces//data/trajectory/`` + - ``~/.cmind/workspaces//logs/`` + - ``/.cmind/reports/`` + - ``~/.cmind/workspaces//.meta.toml`` (refreshed) The inner ``.git/`` directory is NOT created here; that's - the responsibility of :mod:`rpgkit_cli._inner_git`, which seeds an + the responsibility of :mod:`cmind_cli._inner_git`, which seeds an initial commit with a meaningful message. """ # Resolve channel: prefer what's already recorded, fall back to @@ -3622,14 +3621,14 @@ def ensure_rpgkit_runtime_dirs( home_dir = _storage.ensure_workspace_storage( project_path, channel=channel, - rpgkit_cli_version=_current_cli_version(), + cmind_cli_version=_current_cli_version(), ) except _storage.WorkspaceMetaMismatch as exc: # Hash collision or manual rename. Surface clearly: silently # writing into the wrong workspace would corrupt the other # one's data. if tracker: - tracker.add("runtime-dirs", "Ensure ~/.rpgkit/{logs,data} directories") + tracker.add("runtime-dirs", "Ensure ~/.cmind/{logs,data} directories") tracker.error("runtime-dirs", str(exc)) else: console.print(f"[red]error:[/red] {exc}") @@ -3637,7 +3636,7 @@ def ensure_rpgkit_runtime_dirs( except OSError as exc: # Filesystem read-only / permission issue — non-blocking. if tracker: - tracker.add("runtime-dirs", "Ensure ~/.rpgkit/{logs,data} directories") + tracker.add("runtime-dirs", "Ensure ~/.cmind/{logs,data} directories") tracker.error("runtime-dirs", f"could not create: {exc}") return @@ -3650,7 +3649,7 @@ def ensure_rpgkit_runtime_dirs( pass if tracker: - tracker.add("runtime-dirs", "Ensure ~/.rpgkit/{logs,data} directories") + tracker.add("runtime-dirs", "Ensure ~/.cmind/{logs,data} directories") tracker.complete( "runtime-dirs", f"home dir at {home_dir}", @@ -3661,20 +3660,20 @@ def _detect_ai_agent(project_path: Path) -> str | None: """Detect AI agent from existing project directory. Scans for known agent folders (from AGENT_CONFIG) and checks if they - contain rpgkit.* command files. Returns the agent key or None. + contain cmind.* command files. Returns the agent key or None. """ found = [] for key, config in AGENT_CONFIG.items(): agent_dir = project_path / config["folder"] if agent_dir.is_dir(): - # Check common command subdirectories for rpgkit.* files + # Check common command subdirectories for cmind.* files for sub in ("commands", "agents", "prompts"): candidate = agent_dir / sub - if candidate.is_dir() and any(candidate.glob("rpgkit.*")): + if candidate.is_dir() and any(candidate.glob("cmind.*")): found.append(key) break else: - # Folder exists even without rpgkit commands subdirectory + # Folder exists even without cmind commands subdirectory found.append(key) if len(found) == 1: return found[0] @@ -3748,13 +3747,13 @@ def init( "prompt and run, or --no-encode to skip the prompt and not run." ), ), - no_rpgkit_git: bool = typer.Option( + no_cmind_git: bool = typer.Option( False, - "--no-rpgkit-git", + "--no-cmind-git", help=( - "Skip initialising a private git repository inside .rpgkit/. " - "Default is ON: rpgkit init seeds .rpgkit/.git " - "so every subsequent `rpgkit script` invocation auto-snapshots " + "Skip initialising a private git repository inside .cmind/. " + "Default is ON: cmind init seeds .cmind/.git " + "so every subsequent `cmind script` invocation auto-snapshots " "the workspace state, letting you `git log` / `git diff` " "between pipeline stages without extra tooling. This flag " "disables the feature for the current init only." @@ -3772,17 +3771,17 @@ def init( 6. Optionally set up AI assistant commands Examples: - rpgkit init my-project - rpgkit init my-project --ai claude - rpgkit init my-project --ai copilot --no-git - rpgkit init --ignore-agent-tools my-project - rpgkit init . --ai claude # Initialize in current directory - rpgkit init . # Initialize in current directory (interactive AI selection) - rpgkit init --here --ai claude # Alternative syntax for current directory - rpgkit init --here --ai codex - rpgkit init --here --ai codebuddy - rpgkit init --here - rpgkit init --here --force # Skip confirmation when current directory not empty + cmind init my-project + cmind init my-project --ai claude + cmind init my-project --ai copilot --no-git + cmind init --ignore-agent-tools my-project + cmind init . --ai claude # Initialize in current directory + cmind init . # Initialize in current directory (interactive AI selection) + cmind init --here --ai claude # Alternative syntax for current directory + cmind init --here --ai codex + cmind init --here --ai codebuddy + cmind init --here + cmind init --here --force # Skip confirmation when current directory not empty """ show_banner() @@ -3926,7 +3925,7 @@ def init( tracker = StepTracker("Initialize CoderMind Project") - sys._rpgkit_tracker_active = True + sys._cmind_tracker_active = True tracker.add("precheck", "Check required tools") tracker.complete("precheck", "ok") @@ -3970,10 +3969,10 @@ def init( debug=debug, ) - # .rpgkit/.source is written by whichever provisioning path + # .cmind/.source is written by whichever provisioning path # actually ran (_install_from_bundle / _download_and_extract_release_zip). - # Materialise .rpgkit/config.toml with the resolved AI CLI + # Materialise .cmind/config.toml with the resolved AI CLI # command. llm_client.py reads this at runtime to invoke # the right sub-agent. _write_workspace_config(project_path, selected_ai) @@ -4010,7 +4009,7 @@ def init( _register_copilot_cli_global_mcp(tracker=tracker) # Migrate workspaces created before C4: drop the auto-loaded - # rpgkit-codegen.* persistent-instruction files. + # cmind-codegen.* persistent-instruction files. tracker.start("legacy-cleanup") try: removed = _cleanup_legacy_codegen_persistent(project_path) @@ -4077,26 +4076,26 @@ def init( console.print(tracker.render()) console.print("\n[bold green]Project ready.[/bold green]") - # PATH self-check: hooks and MCP rely on ``rpgkit`` / ``rpgkit-mcp`` + # PATH self-check: hooks and MCP rely on ``cmind`` / ``cmind-mcp`` # being resolvable. If they aren't on PATH, the user will hit # opaque failures from git hooks and MCP clients later — surface # the actionable hint now. import shutil as _shutil - if _shutil.which("rpgkit-mcp") is None or _shutil.which("rpgkit") is None: + if _shutil.which("cmind-mcp") is None or _shutil.which("cmind") is None: reinstall_cmd: Optional[list[str]] = _upgrade_command(_detect_install_method()) # ``--force`` reinstalls in place which fixes most PATH issues # caused by partial installs / corrupted shim links. if reinstall_cmd and reinstall_cmd[:3] == ["uv", "tool", "upgrade"]: - reinstall_hint = "uv tool install rpgkit-cli --force" + reinstall_hint = "uv tool install cmind-cli --force" elif reinstall_cmd and reinstall_cmd[:2] == ["pipx", "upgrade"]: - reinstall_hint = "pipx install rpgkit-cli --force" + reinstall_hint = "pipx install cmind-cli --force" elif reinstall_cmd: reinstall_hint = " ".join(reinstall_cmd) else: - reinstall_hint = "uv tool install rpgkit-cli --force # or your installer's equivalent" + reinstall_hint = "uv tool install cmind-cli --force # or your installer's equivalent" console.print() path_panel = Panel( - "[yellow]Warning:[/yellow] [cyan]rpgkit[/cyan] / [cyan]rpgkit-mcp[/cyan] " + "[yellow]Warning:[/yellow] [cyan]cmind[/cyan] / [cyan]cmind-mcp[/cyan] " "not found on PATH.\n\n" "Git hooks and the MCP server invoke these commands; they will " "fail until PATH is fixed.\n\n" @@ -4135,8 +4134,8 @@ def init( else: ignored_path_desc = agent_config["folder"] security_notice = Panel( - f"CoderMind's slash command definitions under [cyan]{ignored_path_desc}[/cyan] are regenerated by [cyan]rpgkit init/update[/cyan] and are excluded from git by default.\n" - f"Collaborators should run [cyan]rpgkit init[/cyan] in their clone to materialize the prompt files locally.", + f"CoderMind's slash command definitions under [cyan]{ignored_path_desc}[/cyan] are regenerated by [cyan]cmind init/update[/cyan] and are excluded from git by default.\n" + f"Collaborators should run [cyan]cmind init[/cyan] in their clone to materialize the prompt files locally.", title="[yellow]Agent Folder Notice[/yellow]", border_style="yellow", padding=(1, 2), @@ -4145,8 +4144,8 @@ def init( console.print(security_notice) # Pre-create runtime directories so early pipeline prompts that redirect - # to ~/.rpgkit/workspaces//logs/.log don't fail with "No such file or directory". - ensure_rpgkit_runtime_dirs(project_path) + # to ~/.cmind/workspaces//logs/.log don't fail with "No such file or directory". + ensure_cmind_runtime_dirs(project_path) steps_lines = [] if not here: @@ -4175,26 +4174,26 @@ def init( steps_lines.append(f"{step_num}. Start using slash commands with your AI agent:") steps_lines.extend([ - f" {step_num}.1 [cyan]/rpgkit.feature_spec[/] - Create feature spec from docs", - f" {step_num}.2 [cyan]/rpgkit.feature_build[/] - Generate and Expand Feature Tree", - f" {step_num}.3 [cyan]/rpgkit.feature_refactor[/] - Refactor Feature Tree", - f" {step_num}.4 [cyan]/rpgkit.feature_edit[/] - Edit Feature Tree Nodes", - f" {step_num}.5 [cyan]/rpgkit.build_skeleton[/] - Repository Skeleton Structure", - f" {step_num}.6 [cyan]/rpgkit.build_data_flow[/] - Data Flow Design", - f" {step_num}.7 [cyan]/rpgkit.design_base_classes[/] - Base Classes Design", - f" {step_num}.8 [cyan]/rpgkit.design_interfaces[/] - Interface Design", - f" {step_num}.9 [cyan]/rpgkit.plan_tasks[/] - Task Planning", - f" {step_num}.10 [cyan]/rpgkit.code_gen[/] - Code Generation", - f" {step_num}.11 [cyan]/rpgkit.rpg_edit[/] - Surgical RPG/code edit", - f" {step_num}.12 [cyan]/rpgkit.encode[/] - Encode repo into RPG", - f" {step_num}.13 [cyan]/rpgkit.update_rpg[/] - Incremental RPG update", + f" {step_num}.1 [cyan]/cmind.feature_spec[/] - Create feature spec from docs", + f" {step_num}.2 [cyan]/cmind.feature_build[/] - Generate and Expand Feature Tree", + f" {step_num}.3 [cyan]/cmind.feature_refactor[/] - Refactor Feature Tree", + f" {step_num}.4 [cyan]/cmind.feature_edit[/] - Edit Feature Tree Nodes", + f" {step_num}.5 [cyan]/cmind.build_skeleton[/] - Repository Skeleton Structure", + f" {step_num}.6 [cyan]/cmind.build_data_flow[/] - Data Flow Design", + f" {step_num}.7 [cyan]/cmind.design_base_classes[/] - Base Classes Design", + f" {step_num}.8 [cyan]/cmind.design_interfaces[/] - Interface Design", + f" {step_num}.9 [cyan]/cmind.plan_tasks[/] - Task Planning", + f" {step_num}.10 [cyan]/cmind.code_gen[/] - Code Generation", + f" {step_num}.11 [cyan]/cmind.rpg_edit[/] - Surgical RPG/code edit", + f" {step_num}.12 [cyan]/cmind.encode[/] - Encode repo into RPG", + f" {step_num}.13 [cyan]/cmind.update_rpg[/] - Incremental RPG update", ]) step_num += 1 steps_lines.append( - f"{step_num}. You can inspect each step's output under [cyan]~/.rpgkit/workspaces//data/[/cyan], " - f"and review detailed execution trajectories under [cyan]~/.rpgkit/workspaces//data/trajectory/[/cyan]. " - f"Run [cyan]rpgkit version[/cyan] from inside the workspace to see the resolved Data / Logs / Inner-git paths." + f"{step_num}. You can inspect each step's output under [cyan]~/.cmind/workspaces//data/[/cyan], " + f"and review detailed execution trajectories under [cyan]~/.cmind/workspaces//data/trajectory/[/cyan]. " + f"Run [cyan]cmind version[/cyan] from inside the workspace to see the resolved Data / Logs / Inner-git paths." ) step_num += 1 @@ -4206,10 +4205,10 @@ def init( # First-run note: the MCP tools are wired up at init time, but they # only return useful data once the encoder has built rpg.json. Make # the requirement loud-and-clear here so users don't hit the silent - # "rpg_unavailable" payload on their first /rpgkit.* call. + # "rpg_unavailable" payload on their first /cmind.* call. steps_lines.append( " [yellow]Note:[/] the MCP tools query [cyan]rpg.json[/] in the workspace's home-dir " - "store, which is created by the encoder. For existing codebases, run [cyan]/rpgkit.encode[/] " + "store, which is created by the encoder. For existing codebases, run [cyan]/cmind.encode[/] " "once now to populate it; the post-commit hook keeps it in sync afterwards." ) @@ -4235,15 +4234,15 @@ def init( console.print() console.print(permissions_hint) - # Initialise the private snapshot repo inside .rpgkit/. Done BEFORE + # Initialise the private snapshot repo inside .cmind/. Done BEFORE # the optional initial encode so the encoder's output, if it runs, # becomes a fresh commit on top of the [init] baseline — a useful # diff target. - if not no_rpgkit_git: + if not no_cmind_git: from . import _inner_git from importlib.metadata import version as _pkg_version, PackageNotFoundError try: - ver = _pkg_version("rpgkit-cli") + ver = _pkg_version("cmind-cli") except PackageNotFoundError: ver = "dev" channel = "bundle" @@ -4255,8 +4254,8 @@ def init( ): console.print( "[dim]Inner snapshot repo initialised at " - "[cyan]~/.rpgkit/workspaces//.git[/cyan] \u2014 " - "run [cyan]rpgkit version[/cyan] for the exact path " + "[cyan]~/.cmind/workspaces//.git[/cyan] \u2014 " + "run [cyan]cmind version[/cyan] for the exact path " "and a ready-to-paste `git -C` invocation.[/dim]" ) @@ -4307,13 +4306,13 @@ def update( "installed the CLI manually." ), ), - no_rpgkit_git: bool = typer.Option( + no_cmind_git: bool = typer.Option( False, - "--no-rpgkit-git", + "--no-cmind-git", help=( - "Skip backfilling the private snapshot repo at .rpgkit/.git " + "Skip backfilling the private snapshot repo at .cmind/.git " "for older workspaces that don't have one yet. Default is ON: " - "if the inner repo is missing, `rpgkit update` creates it and " + "if the inner repo is missing, `cmind update` creates it and " "commits a catch-up snapshot. Pre-existing inner repos are " "never touched." ), @@ -4325,26 +4324,26 @@ def update( config, gitignore rules, and git hooks in the current directory. It auto-detects the AI assistant from existing project configuration. - Equivalent to re-running 'rpgkit init --here --force' but with proper + Equivalent to re-running 'cmind init --here --force' but with proper semantics and automatic detection of existing settings. Examples: - rpgkit update - rpgkit update --ai claude - rpgkit update --no-upgrade + cmind update + cmind update --ai claude + cmind update --no-upgrade """ show_banner() project_path = Path.cwd() - # Verify this is an existing RPG-Kit project - rpgkit_dir = project_path / ".rpgkit" - if not rpgkit_dir.is_dir(): + # Verify this is an existing CoderMind project + cmind_dir = project_path / ".cmind" + if not cmind_dir.is_dir(): console.print( Panel( - "No [cyan].rpgkit/[/cyan] directory found in the current directory.\n" + "No [cyan].cmind/[/cyan] directory found in the current directory.\n" "This command updates an existing CoderMind project.\n\n" - "To create a new project, use: [cyan]rpgkit init[/cyan]", + "To create a new project, use: [cyan]cmind init[/cyan]", title="[red]Not a CoderMind Project[/red]", border_style="red", padding=(1, 2), @@ -4411,8 +4410,8 @@ def update( # Pre-update CLI upgrade ------------------------------------------------- # - # By default, ``rpgkit update`` first runs the appropriate upgrade - # command (``uv tool upgrade rpgkit-cli`` for uv installs etc.) so + # By default, ``cmind update`` first runs the appropriate upgrade + # command (``uv tool upgrade cmind-cli`` for uv installs etc.) so # the workspace's prompts/scripts/templates always match the # *latest* released version of the CLI. Without this, users who # never re-install the CLI would silently drift behind upstream. @@ -4427,16 +4426,16 @@ def update( # re-installed manually). # # After a successful upgrade we ``os.execvp`` the (now-upgraded) - # rpgkit binary so the rest of update runs against the freshly + # cmind binary so the rest of update runs against the freshly # installed code + assets. Mixing old in-memory logic with new # on-disk core_pack/ used to cause logic vs assets drift bugs. # - # Loop guard: ``RPGKIT_UPGRADE_DONE`` is set on the re-exec'd + # Loop guard: ``CMIND_UPGRADE_DONE`` is set on the re-exec'd # process's environment. When present, this block skips the # upgrade attempt unconditionally so an idempotent ``uv tool # upgrade`` (which returns 0 even when there's nothing to upgrade) # doesn't loop forever. - _UPGRADE_DONE_ENV = "RPGKIT_UPGRADE_DONE" + _UPGRADE_DONE_ENV = "CMIND_UPGRADE_DONE" already_upgraded = bool(os.environ.get(_UPGRADE_DONE_ENV)) method = _detect_install_method() @@ -4466,7 +4465,7 @@ def update( if do_upgrade: console.print( - f"[cyan]Upgrading rpgkit-cli via {method} (source={source})...[/cyan]" + f"[cyan]Upgrading cmind-cli via {method} (source={source})...[/cyan]" ) try: rc = subprocess.call(cmd) # type: ignore[arg-type] @@ -4474,7 +4473,7 @@ def update( # Upgrade tool (uv, pipx, pip) not on PATH — surface, then # carry on with the current build. Stripping the upgrade # is a worse user experience than failing fast here would - # be, but ``rpgkit update`` is "make my workspace match the + # be, but ``cmind update`` is "make my workspace match the # installed CLI", and the installed CLI is still functional. console.print( f"[yellow]Upgrade tool {cmd[0]!r} not found on PATH; " @@ -4495,14 +4494,14 @@ def update( # loop-guard env var so the re-exec'd process doesn't # immediately try to upgrade again. new_argv = list(sys.argv) - rpgkit_bin = shutil.which("rpgkit") or new_argv[0] + cmind_bin = shutil.which("cmind") or new_argv[0] console.print( "[cyan]CLI upgrade complete; re-exec'ing to apply " "new templates...[/cyan]" ) try: os.environ[_UPGRADE_DONE_ENV] = "1" - os.execvp(rpgkit_bin, [rpgkit_bin, *new_argv[1:]]) + os.execvp(cmind_bin, [cmind_bin, *new_argv[1:]]) except OSError as exc: # execvp failed — fall back to running the update # in-process with the (now-on-disk) new code. This @@ -4529,7 +4528,7 @@ def update( # Build step tracker tracker = StepTracker("Update CoderMind Project") - sys._rpgkit_tracker_active = True + sys._cmind_tracker_active = True tracker.add("ai-select", "Select AI assistant") tracker.complete("ai-select", f"{selected_ai}") @@ -4567,22 +4566,22 @@ def update( debug=debug, ) - # .rpgkit/.source is written by whichever provisioning path + # .cmind/.source is written by whichever provisioning path # actually ran (_install_from_bundle / _download_and_extract_release_zip). - # Refresh .rpgkit/config.toml only when missing (preserves + # Refresh .cmind/config.toml only when missing (preserves # user customisations on re-update). _write_workspace_config(project_path, selected_ai) # Pre-create runtime directories so stage prompts that redirect - # to ~/.rpgkit/workspaces//logs/.log don't fail when the folder is + # to ~/.cmind/workspaces//logs/.log don't fail when the folder is # missing (e.g. user removed it, or workspace was created by an - # older rpgkit init that didn't pre-create logs/). - ensure_rpgkit_runtime_dirs(project_path, tracker=tracker) + # older cmind init that didn't pre-create logs/). + ensure_cmind_runtime_dirs(project_path, tracker=tracker) - # Ensure RPG-Kit gitignore rules are in place — re-runs are + # Ensure CoderMind gitignore rules are in place — re-runs are # idempotent (existing rules are detected and skipped) and this - # also fixes workspaces created by older rpgkit versions that + # also fixes workspaces created by older cmind versions that # didn't manage gitignore at all. tracker.start("gitignore") try: @@ -4609,7 +4608,7 @@ def update( _register_copilot_cli_global_mcp(tracker=tracker) # Migrate workspaces created before C4: drop the auto-loaded - # rpgkit-codegen.* persistent-instruction files. + # cmind-codegen.* persistent-instruction files. tracker.start("legacy-cleanup") try: removed = _cleanup_legacy_codegen_persistent(project_path) @@ -4626,7 +4625,7 @@ def update( # Re-install hooks so behavior fixes propagate to existing # workspaces. Without this, the .git/hooks/* files stay # frozen at whatever version was active during the original - # `rpgkit init`, and the sentinel-block migration in + # `cmind init`, and the sentinel-block migration in # _install_hook_snippet (the upgrade mechanism for hooks) # never gets a chance to run. _install_hooks(project_path, selected_ai, tracker=tracker) @@ -4671,13 +4670,13 @@ def update( ) # Backfill inner snapshot repo for workspaces created before - # this feature shipped. Idempotent — does nothing if .rpgkit/.git - # already exists, and silently noops if --no-rpgkit-git was passed. - if not no_rpgkit_git: + # this feature shipped. Idempotent — does nothing if .cmind/.git + # already exists, and silently noops if --no-cmind-git was passed. + if not no_cmind_git: from . import _inner_git from importlib.metadata import version as _pkg_version, PackageNotFoundError try: - ver = _pkg_version("rpgkit-cli") + ver = _pkg_version("cmind-cli") except PackageNotFoundError: ver = "dev" if _inner_git.ensure_inner_git( @@ -4686,7 +4685,7 @@ def update( ): console.print( "[dim]Initialised inner snapshot repo at " - "[cyan]~/.rpgkit/workspaces//.git[/cyan] for this workspace.[/dim]" + "[cyan]~/.cmind/workspaces//.git[/cyan] for this workspace.[/dim]" ) @@ -4695,8 +4694,8 @@ def update( "allow_extra_args": True, "ignore_unknown_options": True, # Disable click's auto-help so ``--help`` is forwarded to the - # target script. Use ``rpgkit script`` (no args) or - # ``rpgkit --help script`` to see this command's own help. + # target script. Use ``cmind script`` (no args) or + # ``cmind --help script`` to see this command's own help. "help_option_names": [], }, ) @@ -4728,10 +4727,10 @@ def script( Examples:: - rpgkit script smoke_test.py --json - rpgkit script rpg_edit/validate.py - rpgkit script --list - rpgkit script --where mcp_server.py + cmind script smoke_test.py --json + cmind script rpg_edit/validate.py + cmind script --list + cmind script --where mcp_server.py """ from . import _assets @@ -4752,7 +4751,7 @@ def script( if not relpath: console.print( "[red]error:[/red] missing script path. " - "Use [cyan]rpgkit script --list[/cyan] to see available scripts." + "Use [cyan]cmind script --list[/cyan] to see available scripts." ) raise typer.Exit(2) @@ -4769,7 +4768,7 @@ def script( # Tee stdout to a per-stage log file so the workspace has a persistent # record of every script invocation. The log path is resolved from # _storage at run time; if the home-side dir doesn't exist yet (e.g. - # rpgkit init hasn't run), skip silently — no log is better than + # cmind init hasn't run), skip silently — no log is better than # crashing. log_path: Optional[Path] = None from . import _inner_git as _ig @@ -4803,13 +4802,13 @@ def script( cmd = [sys.executable, str(path), *ctx.args] proc = subprocess.run(cmd, env=env) - # Snapshot the current state of .rpgkit/ into the inner git + # Snapshot the current state of .cmind/ into the inner git # repo so users can `git log` / `git diff` between pipeline stages. # No-op (silently) when the script is read-only (check_*, *_validation), - # the inner repo is absent (--no-rpgkit-git on init), or git is busy. + # the inner repo is absent (--no-cmind-git on init), or git is busy. # # Use the *resolved* path (always carries .py) for the commit message - # so `rpgkit script smoke_test` and `rpgkit script smoke_test.py` + # so `cmind script smoke_test` and `cmind script smoke_test.py` # produce identical history entries. from . import _inner_git, _assets ws_root = _inner_git.find_workspace_root() @@ -4860,7 +4859,7 @@ def _resolve_script_path(relpath: str) -> Optional[Path]: # --------------------------------------------------------------------------- -# Git-hook dispatch: ``rpgkit hook `` +# Git-hook dispatch: ``cmind hook `` # --------------------------------------------------------------------------- # # Python entry-point for git hooks. The on-disk hook files in @@ -4868,8 +4867,8 @@ def _resolve_script_path(relpath: str) -> Optional[Path]: # path resolution, logging, locking, and detach logic live here so they # can be updated by upgrading the CLI rather than reinstalling hooks. -_HOOK_ENV_NAME = "RPGKIT_HOOK" -_HOOK_ENV_SHA = "RPGKIT_HOOK_SHA" +_HOOK_ENV_NAME = "CMIND_HOOK" +_HOOK_ENV_SHA = "CMIND_HOOK_SHA" _HOOK_LOG_FILENAME = "hooks.log" _HOOK_BACKGROUND_LOG = "update_rpg.log" _HOOK_LOCK_DIRNAME = ".update_rpg.lock" @@ -4910,12 +4909,12 @@ def _hook_run_foreground( script_args: List[str], label: str, ) -> int: - """Run ``rpgkit script `` and tee output into ``log_path``.""" + """Run ``cmind script `` and tee output into ``log_path``.""" _hook_log_line(log_path, f"{label}: start ({' '.join(script_args)})") try: with open(log_path, "a", encoding="utf-8") as fh: proc = subprocess.run( - ["rpgkit", "script", *script_args], + ["cmind", "script", *script_args], cwd=str(workspace), env=env, stdout=fh, stderr=subprocess.STDOUT, @@ -4977,7 +4976,7 @@ def _hook_spawn_background( workspace_q = shlex.quote(str(workspace)) shell_cmd = ( f"cd {workspace_q}; sleep 2; " - f"rpgkit script update_graphs.py update-rpg --json >> {log_q} 2>&1; " + f"cmind script update_graphs.py update-rpg --json >> {log_q} 2>&1; " f"rmdir {lock_q}" ) # Strip GIT_INDEX_FILE / GIT_DIR which git sets during hooks - @@ -5013,7 +5012,7 @@ def hook(name: str = typer.Argument(..., help="Hook name: post-commit | post-mer """Dispatch from ``.git/hooks/`` to the matching Python handler. Resolves the current workspace via the standard cwd-walk, attaches - a hook log under ``~/.rpgkit/workspaces//logs/hooks.log``, + a hook log under ``~/.cmind/workspaces//logs/hooks.log``, and runs the per-hook orchestration. Every failure path is swallowed (logged, never raised) so a misbehaving hook never blocks the user's git operation. @@ -5021,16 +5020,16 @@ def hook(name: str = typer.Argument(..., help="Hook name: post-commit | post-mer Supported hooks: ``post-commit`` and ``post-merge``. The dispatcher also accepts ``pre-commit`` as a deliberate no-op for backward compatibility — old workspaces whose hook file still calls - ``rpgkit hook pre-commit`` should be cleaned up on the next - ``rpgkit init`` / ``rpgkit update`` run, which strips the block. + ``cmind hook pre-commit`` should be cleaned up on the next + ``cmind init`` / ``cmind update`` run, which strips the block. - All ``rpgkit script`` subprocess invocations inherit two env vars: + All ``cmind script`` subprocess invocations inherit two env vars: - * ``RPGKIT_HOOK`` -- the hook name (``post-commit`` etc.) - * ``RPGKIT_HOOK_SHA`` -- short SHA of the user-facing commit + * ``CMIND_HOOK`` -- the hook name (``post-commit`` etc.) + * ``CMIND_HOOK_SHA`` -- short SHA of the user-facing commit The inner-git snapshot's commit message picks these up - (:func:`rpgkit_cli._inner_git._build_message`) so ``git log`` in the + (:func:`cmind_cli._inner_git._build_message`) so ``git log`` in the home-side repo reads as a timeline of *user activity*, e.g.:: [hook:post-commit @ a1b2c3d] sync @@ -5041,7 +5040,7 @@ def hook(name: str = typer.Argument(..., help="Hook name: post-commit | post-mer try: ws = _storage.find_workspace_root_from(Path.cwd()) if ws is None: - # Not in an rpgkit workspace -- silently exit success; + # Not in an cmind workspace -- silently exit success; # the hook may be running in a repo that was provisioned # then un-init'd, and we never want to block git. raise typer.Exit(0) @@ -5053,7 +5052,7 @@ def hook(name: str = typer.Argument(..., help="Hook name: post-commit | post-mer env = os.environ.copy() env[_HOOK_ENV_NAME] = name env[_HOOK_ENV_SHA] = sha - # Ensure ``rpgkit`` itself is on PATH when the hook is fired + # Ensure ``cmind`` itself is on PATH when the hook is fired # from a GUI editor that lacks the user's interactive shell PATH. local_bin = str(Path.home() / ".local" / "bin") if local_bin not in env.get("PATH", ""): @@ -5159,7 +5158,7 @@ def version(): # Get CLI version from package metadata cli_version = "unknown" try: - cli_version = importlib.metadata.version("rpgkit-cli") + cli_version = importlib.metadata.version("cmind-cli") except Exception: # Fallback: try reading from pyproject.toml if running from source try: @@ -5180,13 +5179,13 @@ def version(): fetch_error: str | None = None try: - release_data = _fetch_latest_rpgkit_release( + release_data = _fetch_latest_cmind_release( repo_owner, repo_name, client, timeout=10, ) - latest_version = _format_rpgkit_version(release_data.get("tag_name", "unknown")) + latest_version = _format_cmind_version(release_data.get("tag_name", "unknown")) release_date = release_data.get("published_at", "unknown") if release_date != "unknown": # Format the date nicely @@ -5212,7 +5211,7 @@ def version(): status_label = "[yellow]offline[/yellow]" status_hint = ( f"Could not query GitHub for the latest release: {fetch_error}. " - "Local install is still usable; rerun `rpgkit version` when " + "Local install is still usable; rerun `cmind version` when " "you have network access to compare." ) elif cli_version != "unknown" and latest_version != "unknown": @@ -5232,10 +5231,10 @@ def version(): status_hint = ( f"A newer release ([cyan]{latest_version}[/cyan]) is " f"available. Upgrade with one of:\n" - f" [cyan]uv tool upgrade rpgkit-cli[/cyan]\n" - f" [cyan]pipx upgrade rpgkit-cli[/cyan]\n" - f" [cyan]pip install -U rpgkit-cli[/cyan]\n" - f"After upgrading, run [cyan]rpgkit update[/cyan] in each " + f" [cyan]uv tool upgrade cmind-cli[/cyan]\n" + f" [cyan]pipx upgrade cmind-cli[/cyan]\n" + f" [cyan]pip install -U cmind-cli[/cyan]\n" + f"After upgrading, run [cyan]cmind update[/cyan] in each " f"existing workspace to apply the new prompts." ) else: @@ -5261,9 +5260,9 @@ def version(): info_table.add_row("OS Version", platform.version()) # Surface the per-workspace home-side storage when - # invoked from inside an rpgkit workspace. Without this the user + # invoked from inside an cmind workspace. Without this the user # has no obvious way to find their generated artefacts / logs after - # we moved them out of the repo tree into ``~/.rpgkit/workspaces/ + # we moved them out of the repo tree into ``~/.cmind/workspaces/ # /`` — they'd have to derive the workspace id themselves. try: from . import _inner_git @@ -5275,7 +5274,7 @@ def version(): # Annotate each row when the dir doesn't exist yet so the # user doesn't mistake a computed path for a real artefact. # Important after partial cleanup or before the first - # ``rpgkit init`` populates the home-side store — we used + # ``cmind init`` populates the home-side store — we used # to print non-existent paths as if they were live. def _tag(p: Path) -> str: return str(p) if p.exists() else f"{p} [dim](not created yet)[/dim]" @@ -5288,7 +5287,7 @@ def _tag(p: Path) -> str: # (.git exists but zero commits). snapshot_count returns # None for both, so probe has_inner_git directly. if not home_dir.exists(): - inner_git_value = f"{home_dir} [dim](home-side dir not created — run `rpgkit init` here)[/dim]" + inner_git_value = f"{home_dir} [dim](home-side dir not created — run `cmind init` here)[/dim]" elif not _inner_git.has_inner_git(ws): inner_git_value = f"{home_dir} [dim](no inner-git repo)[/dim]" else: diff --git a/CoderMind/src/rpgkit_cli/_assets.py b/CoderMind/src/cmind_cli/_assets.py similarity index 84% rename from CoderMind/src/rpgkit_cli/_assets.py rename to CoderMind/src/cmind_cli/_assets.py index 25c4632..31340ac 100644 --- a/CoderMind/src/rpgkit_cli/_assets.py +++ b/CoderMind/src/cmind_cli/_assets.py @@ -1,17 +1,17 @@ """Locate bundled core_pack assets inside the installed package. The bundle is created at wheel-build time by hatch's ``force-include`` -(see ``pyproject.toml``). After ``uv tool install rpgkit-cli``, the +(see ``pyproject.toml``). After ``uv tool install cmind-cli``, the layout is:: - /lib/python3.x/site-packages/rpgkit_cli/ + /lib/python3.x/site-packages/cmind_cli/ __init__.py _assets.py core_pack/ scripts/ (full CoderMind/scripts/ tree) commands/ (full CoderMind/templates/commands/ tree) -``rpgkit init`` and ``rpgkit update`` copy from here to the workspace +``cmind init`` and ``cmind update`` copy from here to the workspace when bundle mode is active (the default). When the bundle is absent (typically in an editable install where ``force-include`` does not run), :func:`available` returns ``False`` and callers should fall back to the @@ -41,24 +41,24 @@ def core_pack_root() -> Path: Returns the path regardless of whether it exists on disk — callers should check :func:`available` before using the path. """ - return Path(str(files("rpgkit_cli").joinpath("core_pack"))) + return Path(str(files("cmind_cli").joinpath("core_pack"))) def _dev_scripts_dir() -> Path | None: """Locate the repo-root ``scripts/`` directory for editable/dev installs. - When ``rpgkit-cli`` is installed in editable mode (``pip install -e .`` - or ``uv run rpgkit ...`` from the source tree), hatch's - ``force-include`` does not populate ``rpgkit_cli/core_pack/``. In + When ``cmind-cli`` is installed in editable mode (``pip install -e .`` + or ``uv run cmind ...`` from the source tree), hatch's + ``force-include`` does not populate ``cmind_cli/core_pack/``. In that case we fall back to the live source at ``/scripts/``, which sits two levels above this file:: / - src/rpgkit_cli/_assets.py ← __file__ + src/cmind_cli/_assets.py ← __file__ scripts/ ← target """ here = Path(__file__).resolve() - # src/rpgkit_cli/_assets.py → repo = parents[2] + # src/cmind_cli/_assets.py → repo = parents[2] if len(here.parents) >= 3: candidate = here.parents[2] / "scripts" if candidate.is_dir(): @@ -88,10 +88,10 @@ def available() -> bool: def scripts_dir() -> Path: - """Directory containing the RPG-Kit pipeline scripts. + """Directory containing the CoderMind pipeline scripts. Resolution order: - 1. Wheel bundle: ``/rpgkit_cli/core_pack/scripts/`` + 1. Wheel bundle: ``/cmind_cli/core_pack/scripts/`` 2. Dev/editable fallback: ``/scripts/`` Falls back to the wheel path even when missing so error messages @@ -129,7 +129,7 @@ def list_scripts() -> list[str]: """Return all script relative paths (POSIX-style) under :func:`scripts_dir`. Filters to ``.py`` files only, skips ``__pycache__`` directories, - and sorts alphabetically. Used by ``rpgkit script --list``. + and sorts alphabetically. Used by ``cmind script --list``. """ root = scripts_dir() if not root.is_dir(): diff --git a/CoderMind/src/rpgkit_cli/_inner_git.py b/CoderMind/src/cmind_cli/_inner_git.py similarity index 89% rename from CoderMind/src/rpgkit_cli/_inner_git.py rename to CoderMind/src/cmind_cli/_inner_git.py index 85b14b8..e72b3fe 100644 --- a/CoderMind/src/rpgkit_cli/_inner_git.py +++ b/CoderMind/src/cmind_cli/_inner_git.py @@ -1,9 +1,9 @@ """Inner-git snapshotting for the user-home workspace directory. -Every successful (or failed) ``rpgkit script `` invocation +Every successful (or failed) ``cmind script `` invocation auto-commits the current state of the per-workspace home directory at -``~/.rpgkit/workspaces//`` into a dedicated git repo at -``~/.rpgkit/workspaces//.git/``. This lets ``git log`` and +``~/.cmind/workspaces//`` into a dedicated git repo at +``~/.cmind/workspaces//.git/``. This lets ``git log`` and ``git diff`` show how pipeline stages change between runs. What gets tracked: @@ -14,7 +14,7 @@ tracking them lets users ``git log -p logs/.log`` to debug pipeline regressions across snapshots. * ``.meta.toml`` — captures channel + CLI version at each snapshot; - changes only on ``rpgkit init/update``. + changes only on ``cmind init/update``. What is NOT tracked (see :data:`_INNER_GIT_IGNORE` below): @@ -37,7 +37,7 @@ otherwise spam the history). All public functions swallow their own exceptions — this module must -never be a reason ``rpgkit script`` itself fails. +never be a reason ``cmind script`` itself fails. """ from __future__ import annotations @@ -52,15 +52,15 @@ from . import _storage -# Environment variables set by ``rpgkit hook `` before invoking -# any ``rpgkit script`` calls. They flow through every subprocess so +# Environment variables set by ``cmind hook `` before invoking +# any ``cmind script`` calls. They flow through every subprocess so # the snapshot commit message can record *which* git hook fired *which* # user-facing commit instead of just naming the underlying script. # -# Set only by :func:`rpgkit_cli.hook` -- never by manual invocations - -# so the presence of ``RPGKIT_HOOK`` is a reliable trigger-source flag. -_ENV_HOOK_NAME = "RPGKIT_HOOK" # e.g. "post-commit" / "pre-commit" -_ENV_HOOK_SHA = "RPGKIT_HOOK_SHA" # short SHA of the user-facing commit +# Set only by :func:`cmind_cli.hook` -- never by manual invocations - +# so the presence of ``CMIND_HOOK`` is a reliable trigger-source flag. +_ENV_HOOK_NAME = "CMIND_HOOK" # e.g. "post-commit" / "pre-commit" +_ENV_HOOK_SHA = "CMIND_HOOK_SHA" # short SHA of the user-facing commit # --------------------------------------------------------------------------- @@ -69,8 +69,8 @@ # Inner repo identity. Per-call (-c user.X) so this never touches the # user's ~/.gitconfig. -_AUTHOR_EMAIL = "rpgkit@local" -_AUTHOR_NAME = "rpgkit-snapshot" +_AUTHOR_EMAIL = "cmind@local" +_AUTHOR_NAME = "cmind-snapshot" def _author_args() -> list[str]: @@ -99,7 +99,7 @@ def _author_args() -> list[str]: # ``logs/copilot/`` is excluded: it contains full LLM session traces # (typically MB per session) and would dominate the snapshot history. _INNER_GIT_IGNORE = """\ -# Managed by rpgkit-cli: do not edit. +# Managed by cmind-cli: do not edit. # Logs are tracked to support `git log -p logs/.log` debugging. # Exception: logs/copilot/ holds LLM session traces (large, not useful # in history); inspect those files directly. @@ -150,7 +150,7 @@ def categorise_script(relpath: str) -> str: def _inner_git_dir(workspace: Path) -> Path: """Return the home directory used as ``git -C

`` for the snapshots. - The directory is ``~/.rpgkit/workspaces//``; the inner repo's + The directory is ``~/.cmind/workspaces//``; the inner repo's ``.git`` sits directly inside it. """ return _storage.home_workspace_dir(workspace) @@ -160,15 +160,15 @@ def _inner_git_dir(workspace: Path) -> Path: # used in earlier docstrings. No external caller should rely on this; # it stays only to keep grep-friendly when reading older commit # messages and plan documents. -_rpgkit_dir = _inner_git_dir +_cmind_dir = _inner_git_dir def find_workspace_root(start: Optional[Path] = None) -> Optional[Path]: """Walk up from ``start`` (default cwd) looking for a workspace marker. - Returns the directory containing ``.rpgkit/config.toml`` (the + Returns the directory containing ``.cmind/config.toml`` (the workspace marker), or ``None`` if not found. Used by - ``rpgkit script`` to figure out which workspace's inner git repo to + ``cmind script`` to figure out which workspace's inner git repo to snapshot into when the caller's cwd is a subdirectory. """ return _storage.find_workspace_root_from(start) @@ -200,7 +200,7 @@ def _run_git(workspace: Path, *args: str, check: bool = False, timeout: int = 30 # Strip inherited git env vars: a foreground hook caller may have set # GIT_INDEX_FILE / GIT_DIR / GIT_WORK_TREE pointing at the outer repo. # If we leak those into the inner-git call the outer repo's index gets - # corrupted (entries from $HOME/.rpgkit get written into the outer index.lock). + # corrupted (entries from $HOME/.cmind get written into the outer index.lock). for _v in ("GIT_INDEX_FILE", "GIT_DIR", "GIT_WORK_TREE", "GIT_OBJECT_DIRECTORY"): env.pop(_v, None) cmd = ["git", "-C", str(_inner_git_dir(workspace))] + list(args) @@ -219,14 +219,14 @@ def _run_git(workspace: Path, *args: str, check: bool = False, timeout: int = 30 # --------------------------------------------------------------------------- def ensure_inner_git(workspace: Path, *, initial_msg: Optional[str] = None) -> bool: - """Create ``~/.rpgkit/workspaces//.git`` if missing. + """Create ``~/.cmind/workspaces//.git`` if missing. Returns ``True`` when a fresh repo was created, ``False`` when it already existed or when setup was skipped (git missing, home dir unavailable, …). The home dir must already exist — it's the responsibility of - ``ensure_workspace_storage`` (called from ``rpgkit init/update`` + ``ensure_workspace_storage`` (called from ``cmind init/update`` earlier in the bootstrap) to create it. We don't create it here because that requires picking a ``channel`` (bundle vs legacy), which is information only the caller has. @@ -260,7 +260,7 @@ def ensure_inner_git(workspace: Path, *, initial_msg: Optional[str] = None) -> b pass # Initial commit — even if empty, it gives `git log` a starting point. - initial_msg = initial_msg or "[init] rpgkit workspace" + initial_msg = initial_msg or "[init] cmind workspace" _commit_all(workspace, initial_msg, allow_empty=True) return True @@ -303,7 +303,7 @@ def _commit_all(workspace: Path, message: str, *, allow_empty: bool = False) -> """Stage everything and commit. Returns True iff a commit was created. Concurrent-safe: if the index lock is held by a parallel git process - (e.g. the post-commit hook firing ``rpgkit script update_graphs.py`` + (e.g. the post-commit hook firing ``cmind script update_graphs.py`` in the background), we retry once after a short sleep, then give up silently. The next successful commit will fold in any deferred changes — no data is lost. @@ -339,15 +339,15 @@ def _commit_all(workspace: Path, message: str, *, allow_empty: bool = False) -> # --------------------------------------------------------------------------- -# Public entry: after a `rpgkit script ` call +# Public entry: after a `cmind script ` call # --------------------------------------------------------------------------- def _build_message(script_relpath: str, args: list[str], exit_code: int) -> str: - """Compose the inner-git commit message for a ``rpgkit script`` call. + """Compose the inner-git commit message for a ``cmind script`` call. Two output shapes: - * **Hook-triggered** (``RPGKIT_HOOK`` is set by ``rpgkit hook``):: + * **Hook-triggered** (``CMIND_HOOK`` is set by ``cmind hook``):: [hook:post-commit @ a1b2c3d] update-rpg [hook:pre-commit @ a1b2c3d] sync --staged-only @@ -356,7 +356,7 @@ def _build_message(script_relpath: str, args: list[str], exit_code: int) -> str: SHA are surfaced so ``git log`` in the inner repo reads as a timeline of *user activity*, not a timeline of internal scripts. - * **Manual** (no ``RPGKIT_HOOK``):: + * **Manual** (no ``CMIND_HOOK``):: [decoder] feature_build.py [encoder] rpg_encoder/run_encode.py --json @@ -402,10 +402,10 @@ def auto_commit_after_script( args: list[str], exit_code: int, ) -> None: - """Snapshot ``.rpgkit/`` after a ``rpgkit script`` call completes. + """Snapshot ``.cmind/`` after a ``cmind script`` call completes. No-ops (silently) when any of: - * ``.rpgkit/.git`` is missing + * ``.cmind/.git`` is missing * the script matches a skip pattern * git is unavailable * the index is locked and the retry still fails @@ -424,7 +424,7 @@ def auto_commit_after_script( # --------------------------------------------------------------------------- -# `rpgkit version` helper +# `cmind version` helper # --------------------------------------------------------------------------- def snapshot_count(workspace: Path) -> Optional[int]: diff --git a/CoderMind/src/rpgkit_cli/_storage.py b/CoderMind/src/cmind_cli/_storage.py similarity index 87% rename from CoderMind/src/rpgkit_cli/_storage.py rename to CoderMind/src/cmind_cli/_storage.py index 59ad3e0..bc5fcc9 100644 --- a/CoderMind/src/rpgkit_cli/_storage.py +++ b/CoderMind/src/cmind_cli/_storage.py @@ -1,9 +1,9 @@ -"""Home-directory workspace storage layout for RPG-Kit. +"""Home-directory workspace storage layout for CoderMind. -Replaces the legacy ``workspace/.rpgkit/{data,logs,.git}`` layout with a -centralised one rooted at ``~/.rpgkit/``: +Replaces the legacy ``workspace/.cmind/{data,logs,.git}`` layout with a +centralised one rooted at ``~/.cmind/``: - ~/.rpgkit/ + ~/.cmind/ workspaces// .meta.toml {workspace_path, channel, created_at, last_seen_at} .git/ inner git snapshot repo @@ -12,7 +12,7 @@ The workspace itself retains only two minimal items:: - /.rpgkit/ + /.cmind/ config.toml AI configuration (team-shared, committed) reports/ user-facing reports (e.g. rpg.html) @@ -35,7 +35,7 @@ collision aborts cleanly rather than silently overwriting state. Why a readable slug and not a flat hash? Users routinely browse -``~/.rpgkit/workspaces/`` to find logs, delete stale state, or sanity- +``~/.cmind/workspaces/`` to find logs, delete stale state, or sanity- check which workspace a process is talking to; a slug makes that ten times easier than an opaque hex hash. We accept a small (negligible in practice) collision risk in exchange. @@ -48,8 +48,8 @@ ---------- The "workspace root" is discovered by walking up from the caller's -current directory looking for the marker ``.rpgkit/config.toml``. Both -the MCP server and ``rpgkit script `` use the same logic so a user +current directory looking for the marker ``.cmind/config.toml``. Both +the MCP server and ``cmind script `` use the same logic so a user who ``cd``-s into any subdirectory of a workspace gets the right home directory automatically. @@ -57,7 +57,7 @@ -------------- * :func:`workspace_id` - the slug (or slug+hash suffix) for a workspace path. -* :func:`home_workspace_dir` - ``~/.rpgkit/workspaces//``. +* :func:`home_workspace_dir` - ``~/.cmind/workspaces//``. * :func:`workspace_data_dir`, :func:`workspace_logs_dir`, :func:`workspace_inner_git_dir`, :func:`workspace_reports_dir` - convenience wrappers for the four canonical subdirectories. @@ -76,7 +76,7 @@ * All path inputs are run through :py:meth:`Path.resolve` so symlinked workspace roots map to a single canonical id. * All filesystem mutations are best-effort idempotent so re-running - ``rpgkit init`` or ``rpgkit update`` is safe. + ``cmind init`` or ``cmind update`` is safe. """ from __future__ import annotations @@ -98,12 +98,12 @@ # Public constants # --------------------------------------------------------------------------- -#: Subdirectory of the user's home where rpgkit keeps all per-workspace data. -HOME_ROOT_RELPATH = Path(".rpgkit") / "workspaces" +#: Subdirectory of the user's home where cmind keeps all per-workspace data. +HOME_ROOT_RELPATH = Path(".cmind") / "workspaces" -#: Marker file inside the workspace that identifies it as an rpgkit -#: workspace. ``rpgkit init`` writes this; cwd-walk-up looks for it. -WORKSPACE_MARKER_RELPATH = Path(".rpgkit") / "config.toml" +#: Marker file inside the workspace that identifies it as an cmind +#: workspace. ``cmind init`` writes this; cwd-walk-up looks for it. +WORKSPACE_MARKER_RELPATH = Path(".cmind") / "config.toml" #: Standard subdirectories created under each home workspace dir. _DATA_SUBDIR = "data" @@ -113,7 +113,7 @@ #: Reports directory inside the workspace (small, user-facing artefacts #: like ``rpg.html``). -WORKSPACE_REPORTS_SUBDIR = Path(".rpgkit") / "reports" +WORKSPACE_REPORTS_SUBDIR = Path(".cmind") / "reports" #: Channel values written to ``.meta.toml``. CHANNEL_BUNDLE = "bundle" @@ -164,7 +164,7 @@ def _slugify_path(workspace_path: Path) -> str: use as a directory name on every filesystem we target. Examples: - ``/home/hys/projects/rpgkit`` -> ``home-hys-projects-rpgkit`` + ``/home/hys/projects/cmind`` -> ``home-hys-projects-cmind`` ``C:\\Users\\foo\\bar`` -> ``c-users-foo-bar`` ``/`` -> ``root`` """ @@ -202,8 +202,8 @@ def workspace_id(workspace_path: Path) -> str: Two formats: * **Short (preferred)** — when the path slug is ≤ 200 chars, use - the slug verbatim, e.g. ``home-hys-projects-rpgkit``. Readable - at a glance; lets users browse ``~/.rpgkit/workspaces/`` and + the slug verbatim, e.g. ``home-hys-projects-cmind``. Readable + at a glance; lets users browse ``~/.cmind/workspaces/`` and identify their projects without cross-referencing a hash table. * **Truncated (overflow)** — when the slug exceeds the budget, keep the first ~193 chars and append ``-`` where @@ -230,7 +230,7 @@ def workspace_id(workspace_path: Path) -> str: # --------------------------------------------------------------------------- def home_root() -> Path: - """Return ``~/.rpgkit/workspaces/``. + """Return ``~/.cmind/workspaces/``. Does not create the directory; callers should use :func:`ensure_workspace_storage` when they need it to exist. @@ -241,11 +241,11 @@ def home_root() -> Path: def home_workspace_dir(workspace_path: Path) -> Path: """Return the home directory assigned to ``workspace_path``. - Normally this is ``~/.rpgkit/workspaces//`` using the + Normally this is ``~/.cmind/workspaces//`` using the slug-based id from :func:`workspace_id`. Backward compatibility: if a directory under the **legacy** 12-char - hex id already exists on disk (created by rpgkit < 0.1.4) and no + hex id already exists on disk (created by cmind < 0.1.4) and no slug-named directory exists for the same path, the legacy directory is returned so the user keeps reaching their existing state after upgrading. New workspaces always use the slug-based layout. @@ -301,7 +301,7 @@ def workspace_reports_dir(workspace_path: Path) -> Path: def _is_live_workspace_root(root: Path) -> bool: """Return True iff a candidate workspace root is still live. - A bare ``.rpgkit/config.toml`` is enough for a *fresh* workspace + A bare ``.cmind/config.toml`` is enough for a *fresh* workspace (the marker may be planted before any home-side state is written), so the marker alone is treated as live until proven stale. @@ -322,10 +322,10 @@ def _is_live_workspace_root(root: Path) -> bool: def find_workspace_root_from(start: Optional[Path] = None) -> Optional[Path]: - """Walk up from ``start`` (default: cwd) looking for an rpgkit workspace. + """Walk up from ``start`` (default: cwd) looking for an cmind workspace. A directory qualifies as a workspace if it contains - ``.rpgkit/config.toml`` (see :data:`WORKSPACE_MARKER_RELPATH`) + ``.cmind/config.toml`` (see :data:`WORKSPACE_MARKER_RELPATH`) **and** passes :func:`_is_live_workspace_root` — i.e. either it has no ``.meta.toml`` (fresh workspace), or the recorded ``workspace_path`` in meta still matches. Stale (moved/renamed) @@ -395,7 +395,7 @@ def write_meta( workspace_path: Path, *, channel: str, - rpgkit_cli_version: Optional[str] = None, + cmind_cli_version: Optional[str] = None, preserve_created_at: bool = True, ) -> None: """Atomically write the workspace's ``.meta.toml``. @@ -404,9 +404,9 @@ def write_meta( workspace_path: The workspace directory (resolved internally). channel: ``"bundle"`` or ``"legacy"`` -- which provisioning channel was used. - rpgkit_cli_version: The installed rpgkit-cli version at write - time. Stored as ``rpgkit_cli_version_at_init`` (only on - first write) and ``rpgkit_cli_version_last_seen`` (every + cmind_cli_version: The installed cmind-cli version at write + time. Stored as ``cmind_cli_version_at_init`` (only on + first write) and ``cmind_cli_version_last_seen`` (every write). preserve_created_at: When True (the default), keep the original ``created_at`` from any existing meta file; otherwise @@ -430,19 +430,19 @@ def write_meta( if preserve_created_at: created_at = existing.get("created_at", now) # On preserve, also carry forward the version recorded at init - # so re-running ``rpgkit update`` doesn't blow away that history. + # so re-running ``cmind update`` doesn't blow away that history. init_version = existing.get( - "rpgkit_cli_version_at_init", rpgkit_cli_version or "" + "cmind_cli_version_at_init", cmind_cli_version or "" ) else: # "Reset" semantics: created_at and init_version both refresh # to the values supplied in this call. created_at = now - init_version = rpgkit_cli_version or "" + init_version = cmind_cli_version or "" # Serialise by hand - tiny + avoids a TOML writer dep. lines = [ - "# RPG-Kit per-workspace state. Managed by `rpgkit init/update`.", + "# CoderMind per-workspace state. Managed by `cmind init/update`.", "# Do not commit; recreated automatically if missing.", "", f'workspace_path = "{_toml_escape(str(resolved))}"', @@ -451,10 +451,10 @@ def write_meta( f'last_seen_at = "{now}"', ] if init_version: - lines.append(f'rpgkit_cli_version_at_init = "{_toml_escape(init_version)}"') - if rpgkit_cli_version: + lines.append(f'cmind_cli_version_at_init = "{_toml_escape(init_version)}"') + if cmind_cli_version: lines.append( - f'rpgkit_cli_version_last_seen = "{_toml_escape(rpgkit_cli_version)}"' + f'cmind_cli_version_last_seen = "{_toml_escape(cmind_cli_version)}"' ) payload = "\n".join(lines) + "\n" @@ -481,7 +481,7 @@ class WorkspaceMetaMismatch(RuntimeError): This indicates either a hash collision (statistically very rare for a 48-bit truncated hash on a single machine, but possible) or a - user manually moving directories under ``~/.rpgkit/``. We never + user manually moving directories under ``~/.cmind/``. We never silently mix two workspaces' data; the user must investigate. """ @@ -490,13 +490,13 @@ def ensure_workspace_storage( workspace_path: Path, *, channel: str, - rpgkit_cli_version: Optional[str] = None, + cmind_cli_version: Optional[str] = None, ) -> Path: """Create the home layout for ``workspace_path`` (idempotent). Creates:: - ~/.rpgkit/workspaces// + ~/.cmind/workspaces// data/ logs/ @@ -507,11 +507,11 @@ def ensure_workspace_storage( rather than overwriting another workspace's data. The inner ``.git/`` directory is NOT created here; that's the - responsibility of :mod:`rpgkit_cli._inner_git`, which knows how to + responsibility of :mod:`cmind_cli._inner_git`, which knows how to seed an initial commit message. Returns: - The home workspace directory (``~/.rpgkit/workspaces//``). + The home workspace directory (``~/.cmind/workspaces//``). """ resolved = _resolve(workspace_path) home_dir = home_workspace_dir(resolved) @@ -532,7 +532,7 @@ def ensure_workspace_storage( (home_dir / _LOGS_SUBDIR).mkdir(parents=True, exist_ok=True) workspace_reports_dir(resolved).mkdir(parents=True, exist_ok=True) - write_meta(resolved, channel=channel, rpgkit_cli_version=rpgkit_cli_version) + write_meta(resolved, channel=channel, cmind_cli_version=cmind_cli_version) return home_dir diff --git a/CoderMind/src/rpgkit_cli/entries.py b/CoderMind/src/cmind_cli/entries.py similarity index 76% rename from CoderMind/src/rpgkit_cli/entries.py rename to CoderMind/src/cmind_cli/entries.py index 83c3d04..469e512 100644 --- a/CoderMind/src/rpgkit_cli/entries.py +++ b/CoderMind/src/cmind_cli/entries.py @@ -1,8 +1,8 @@ -"""Console-script entries for ``rpgkit-cli``. +"""Console-script entries for ``cmind-cli``. Currently provides: -* :func:`mcp_main` — the ``rpgkit-mcp`` console script. Sets up +* :func:`mcp_main` — the ``cmind-mcp`` console script. Sets up ``sys.path`` so that the bundled ``scripts/`` directory is importable, then hands off to ``mcp_server.main()``. @@ -26,8 +26,8 @@ def mcp_main() -> None: scripts_dir = _assets.scripts_dir() if not scripts_dir.is_dir(): sys.stderr.write( - "rpgkit-mcp: packaged scripts directory unavailable. " - "Try reinstalling: `uv tool install rpgkit-cli --force`.\n" + "cmind-mcp: packaged scripts directory unavailable. " + "Try reinstalling: `uv tool install cmind-cli --force`.\n" ) sys.exit(2) @@ -38,7 +38,7 @@ def mcp_main() -> None: try: from mcp_server import main as _mcp_server_main # type: ignore[import-not-found] except Exception as exc: # pragma: no cover - import-time failure surface - sys.stderr.write(f"rpgkit-mcp: failed to import mcp_server: {exc}\n") + sys.stderr.write(f"cmind-mcp: failed to import mcp_server: {exc}\n") sys.exit(3) _mcp_server_main() diff --git a/CoderMind/templates/commands/build_data_flow.md b/CoderMind/templates/commands/build_data_flow.md index aca1014..7f2b34b 100644 --- a/CoderMind/templates/commands/build_data_flow.md +++ b/CoderMind/templates/commands/build_data_flow.md @@ -1,6 +1,6 @@ --- description: Build inter-component data flow graph (DAG) -name: rpgkit.build_data_flow +name: cmind.build_data_flow --- ## User Input @@ -16,13 +16,13 @@ All the bash command timeout is set to 1 hour. ## **Outline** -The text entered by the user after `/rpgkit.build_data_flow` **is the adjustment suggestion**. +The text entered by the user after `/cmind.build_data_flow` **is the adjustment suggestion**. Unless it is explicitly empty, you may assume it is always available as `$ARGUMENTS`. **Do not** ask the user to repeat the input. ### Step 1: Pre-check -Run the script `rpgkit script check_data_flow.py` to verify the current state. +Run the script `cmind script check_data_flow.py` to verify the current state. 1. Inspect the `state` field in the output: @@ -69,7 +69,7 @@ Run the script `rpgkit script check_data_flow.py` to verify the current state. 1. Display the following prompt and wait for user confirmation: ```text - Description: Run the script `rpgkit script build_data_flow.py` to: + Description: Run the script `cmind script build_data_flow.py` to: - Design inter-component data flow as a DAG - Generate subtree processing order @@ -81,7 +81,7 @@ Run the script `rpgkit script check_data_flow.py` to verify the current state. 2. Execute the following command with the selected iteration count: ```bash - rpgkit script build_data_flow.py --max-iterations + cmind script build_data_flow.py --max-iterations ``` The script writes a structured log automatically; @@ -97,7 +97,7 @@ Run the script `rpgkit script check_data_flow.py` to verify the current state. - Components: - Subtree Order: - Output: .rpgkit/data/data_flow.json + Output: .cmind/data/data_flow.json ``` ### Step 3: Validation @@ -105,7 +105,7 @@ Run the script `rpgkit script check_data_flow.py` to verify the current state. Run the validation script: ```bash -rpgkit script check_data_flow.py --verbose +cmind script check_data_flow.py --verbose ``` Display the validation results to the user: @@ -125,29 +125,29 @@ Display the validation results to the user: Run the visualization script: ```bash -rpgkit script generate_viz.py +cmind script generate_viz.py ``` Report: * Status of data flow building * Summary of edges and subtree order -* Preparedness for next stage (`/rpgkit.design_base_classes` or `/rpgkit.design_interfaces`) +* Preparedness for next stage (`/cmind.design_base_classes` or `/cmind.design_interfaces`) Prompt the user: ```text Data flow has been generated. Review the file structure at: -.rpgkit/data/data_flow.json +.cmind/data/data_flow.json Visualization generated at: -.rpgkit/data/data_flow_viz.html (Open in browser to inspect) +.cmind/data/data_flow_viz.html (Open in browser to inspect) To proceed with base class design, run: -/rpgkit.design_base_classes +/cmind.design_base_classes To regenerate with adjustments, run: -/rpgkit.build_data_flow +/cmind.build_data_flow ``` **If keeping existing data flow:** @@ -160,5 +160,5 @@ Current data flow: - Components: - Subtree Order: -Next step: Run /rpgkit.design_base_classes +Next step: Run /cmind.design_base_classes ``` diff --git a/CoderMind/templates/commands/build_skeleton.md b/CoderMind/templates/commands/build_skeleton.md index 695721b..278619a 100644 --- a/CoderMind/templates/commands/build_skeleton.md +++ b/CoderMind/templates/commands/build_skeleton.md @@ -1,6 +1,6 @@ --- description: Build repository file skeleton from component architecture -name: rpgkit.build_skeleton +name: cmind.build_skeleton --- ## User Input @@ -14,17 +14,17 @@ proceed with default behavior. ## **Outline** -The text entered by the user after `/rpgkit.build_skeleton` **is the adjustment suggestion**. +The text entered by the user after `/cmind.build_skeleton` **is the adjustment suggestion**. Unless it is explicitly empty, you may assume it is always available as `$ARGUMENTS`. **Do not** ask the user to repeat the input. ### Step 1: Pre-check -Run the script `rpgkit script check_skeleton.py` to verify the current state. +Run the script `cmind script check_skeleton.py` to verify the current state. 1. Inspect the `type` field in the output: - * `error` → Display the error message and stop. Instruct user to run `/rpgkit.refactor_feature` first. Terminate this command. + * `error` → Display the error message and stop. Instruct user to run `/cmind.refactor_feature` first. Terminate this command. * `init` → Proceed to Step 2. * `warning` → Display the following prompt and wait for user confirmation: @@ -57,7 +57,7 @@ Run the script `rpgkit script check_skeleton.py` to verify the current state. 1. Display the following prompt and wait for user confirmation: ```text - Description: Run the script `rpgkit script build_skeleton.py` to: + Description: Run the script `cmind script build_skeleton.py` to: - Step 1: Design directory structure for components - Step 2: Assign features to Python files @@ -69,7 +69,7 @@ Run the script `rpgkit script check_skeleton.py` to verify the current state. 2. Execute the following command with the selected iteration count: ```bash - rpgkit script build_skeleton.py --max-iterations + cmind script build_skeleton.py --max-iterations ``` The script writes a structured log automatically; @@ -92,7 +92,7 @@ Run the script `rpgkit script check_skeleton.py` to verify the current state. Run the validation script: ```bash -rpgkit script check_skeleton.py --verbose +cmind script check_skeleton.py --verbose ``` Display the validation results to the user: @@ -110,7 +110,7 @@ Display the validation results to the user: Run the summary script to generate a formatted report and save to file: ```bash -rpgkit script summary_skeleton.py +cmind script summary_skeleton.py ``` The summary (including directory structure, component paths, and statistics) is @@ -127,8 +127,8 @@ Outputs (managed by the script; consumed by downstream stages): skeleton_summary.txt - Human-readable summary To proceed with data flow design, run: - /rpgkit.build_data_flow + /cmind.build_data_flow To regenerate with adjustments, run: - /rpgkit.build_skeleton + /cmind.build_skeleton ``` diff --git a/CoderMind/templates/commands/code_gen.md b/CoderMind/templates/commands/code_gen.md index 5dcaf2e..40df473 100644 --- a/CoderMind/templates/commands/code_gen.md +++ b/CoderMind/templates/commands/code_gen.md @@ -1,5 +1,5 @@ --- -name: rpgkit.code_gen +name: cmind.code_gen description: Implement code using TDD workflow with iterative test-code-fix cycles --- @@ -18,7 +18,7 @@ runs pytest, and fixes issues — up to 5 iterations per attempt, 2 attempts per Run the check script to determine current state: ```bash -rpgkit script check_code_gen.py --json +cmind script check_code_gen.py --json ``` **If type is "error"**: @@ -31,7 +31,7 @@ rpgkit script check_code_gen.py --json **If type is "in_progress"**: -* Run `rpgkit script run_batch.py --resume --json` to resume +* Run `cmind script run_batch.py --resume --json` to resume **If type is "complete"**: @@ -42,7 +42,7 @@ rpgkit script check_code_gen.py --json **This step is only needed once**, before the first batch. ```bash -rpgkit script init_codebase.py --json +cmind script init_codebase.py --json ``` This creates README.md, .gitignore, base classes, and an initial commit. @@ -96,19 +96,19 @@ Remember both choices for the session. **Single-batch mode:** ```bash -rpgkit script run_batch.py --next --json +cmind script run_batch.py --next --json ``` **File-merge mode (no unit limit):** ```bash -rpgkit script run_batch.py --next --merge-file --json +cmind script run_batch.py --next --merge-file --json ``` **File-merge mode (with unit limit):** ```bash -rpgkit script run_batch.py --next --merge-file --max-units --json +cmind script run_batch.py --next --merge-file --max-units --json ``` **Read the JSON output:** @@ -129,7 +129,7 @@ Continue until `type` is `"complete"` or no tasks remain. When all batches are processed: ```bash -rpgkit script run_batch.py --final-test --json +cmind script run_batch.py --final-test --json ``` This runs pytest (full suite) and smoke test (import check, entry point, stub detection). @@ -140,7 +140,7 @@ If smoke test reports errors, a repair agent is dispatched automatically. After final test passes, run the global review: ```bash -rpgkit script run_batch.py --global-review --json +cmind script run_batch.py --global-review --json ``` This dispatches a sub-agent that: @@ -167,7 +167,7 @@ This step can be re-run independently without re-running `--final-test`. Next steps: • Review failed batches (branches preserved for inspection) - • Run: rpgkit script run_batch.py --retry --json + • Run: cmind script run_batch.py --retry --json ``` --- @@ -176,19 +176,19 @@ This step can be re-run independently without re-running `--final-test`. ```bash # Resume an interrupted batch -rpgkit script run_batch.py --resume --json +cmind script run_batch.py --resume --json # Retry a specific failed batch -rpgkit script run_batch.py --retry --json +cmind script run_batch.py --retry --json # Run a specific batch by ID -rpgkit script run_batch.py --batch-id --json +cmind script run_batch.py --batch-id --json # Repo validation (pytest + smoke) -rpgkit script run_batch.py --final-test --json +cmind script run_batch.py --final-test --json # Full feature review + visual QA -rpgkit script run_batch.py --global-review --json +cmind script run_batch.py --global-review --json ``` ## Recovery @@ -196,11 +196,11 @@ rpgkit script run_batch.py --global-review --json To resume from any state: ```bash -rpgkit script check_code_gen.py --json +cmind script check_code_gen.py --json ``` Follow the `next_action` field — it always tells you the exact command to run. -State is persisted in `.rpgkit/data/code_gen_state.jsonl`. +State is persisted in `.cmind/data/code_gen_state.jsonl`. ## Notes diff --git a/CoderMind/templates/commands/design_base_classes.md b/CoderMind/templates/commands/design_base_classes.md index 4bfbafb..1f775dc 100644 --- a/CoderMind/templates/commands/design_base_classes.md +++ b/CoderMind/templates/commands/design_base_classes.md @@ -1,6 +1,6 @@ --- description: Design shared base classes and data structures -name: rpgkit.design_base_classes +name: cmind.design_base_classes --- ## User Input @@ -14,13 +14,13 @@ proceed with default behavior. ## **Outline** -The text entered by the user after `/rpgkit.design_base_classes` **is the adjustment suggestion**. +The text entered by the user after `/cmind.design_base_classes` **is the adjustment suggestion**. Unless it is explicitly empty, you may assume it is always available as `$ARGUMENTS`. **Do not** ask the user to repeat the input. ### Step 1: Pre-check -Run the script `rpgkit script check_base_classes.py` to verify the current state. +Run the script `cmind script check_base_classes.py` to verify the current state. 1. Inspect the `state` field in the output: @@ -52,7 +52,7 @@ Run the script `rpgkit script check_base_classes.py` to verify the current state 1. Display the following prompt and wait for user confirmation: ```text - Description: Run the script `rpgkit script design_base_classes.py` to: + Description: Run the script `cmind script design_base_classes.py` to: - Design functional base classes (behavioral abstractions) - Design global data structures (shared data formats) @@ -66,7 +66,7 @@ Run the script `rpgkit script check_base_classes.py` to verify the current state 2. Execute the following command with the selected iteration count: ```bash - rpgkit script design_base_classes.py --max-iterations + cmind script design_base_classes.py --max-iterations ``` The script writes a structured log automatically; @@ -84,7 +84,7 @@ Run the script `rpgkit script check_base_classes.py` to verify the current state Classes: - Output: .rpgkit/data/base_classes.json + Output: .cmind/data/base_classes.json ``` ### Step 3: Validation @@ -92,7 +92,7 @@ Run the script `rpgkit script check_base_classes.py` to verify the current state Run the validation script: ```bash -rpgkit script check_base_classes.py --verbose +cmind script check_base_classes.py --verbose ``` Display the validation results to the user: @@ -112,19 +112,19 @@ Report: * Status of base class design * Summary of classes and files -* Preparedness for next stage (`/rpgkit.design_interfaces`) +* Preparedness for next stage (`/cmind.design_interfaces`) Prompt the user: ```text Base classes have been designed. Review the file at: -.rpgkit/data/base_classes.json +.cmind/data/base_classes.json To proceed with interface design, run: -/rpgkit.design_interfaces +/cmind.design_interfaces To regenerate with adjustments, run: -/rpgkit.design_base_classes +/cmind.design_base_classes ``` **If keeping existing:** @@ -136,7 +136,7 @@ Current base classes: - Base Classes: - Files: -Next step: Run /rpgkit.design_interfaces +Next step: Run /cmind.design_interfaces ``` If no base classes file, display an error: @@ -145,5 +145,5 @@ If no base classes file, display an error: ✗ Error: base_classes.json not found. This step is required before proceeding to interface design. -Please run /rpgkit.design_base_classes to generate base classes. +Please run /cmind.design_base_classes to generate base classes. ``` diff --git a/CoderMind/templates/commands/design_interfaces.md b/CoderMind/templates/commands/design_interfaces.md index 512e5ea..17be483 100644 --- a/CoderMind/templates/commands/design_interfaces.md +++ b/CoderMind/templates/commands/design_interfaces.md @@ -1,5 +1,5 @@ --- -name: rpgkit.design_interfaces +name: cmind.design_interfaces description: Design interfaces (functions/classes) for repository files --- @@ -16,7 +16,7 @@ Design function and class interfaces for your repository files based on the skel Run the check script to determine current state: ```bash -rpgkit script check_interfaces.py --json +cmind script check_interfaces.py --json ``` **If type is "error"**: @@ -62,7 +62,7 @@ rpgkit script check_interfaces.py --json Run the interface designer: ```bash -rpgkit script design_interfaces.py +cmind script design_interfaces.py ``` The script writes a structured log automatically; stdout carries the @@ -76,7 +76,7 @@ This will: 4. For each file, design the appropriate functions and classes 5. Generate signatures with type hints and comprehensive docstrings 6. Map each unit to the features it implements -7. Save the results to `.rpgkit/data/interfaces.json` +7. Save the results to `.cmind/data/interfaces.json` Note: If data_flow.json exists, components are processed in the subtree order defined by the data flow DAG. This ensures dependencies are resolved correctly. @@ -86,7 +86,7 @@ defined by the data flow DAG. This ensures dependencies are resolved correctly. After generation, run the check script again: ```bash -rpgkit script check_interfaces.py --json +cmind script check_interfaces.py --json ``` Verify: @@ -111,5 +111,5 @@ Guide user to the next step: ```text > Interface design complete! Your next step is: > -> **/rpgkit.plan_tasks** - Create implementation tasks +> **/cmind.plan_tasks** - Create implementation tasks ``` diff --git a/CoderMind/templates/commands/encode.md b/CoderMind/templates/commands/encode.md index 7651917..4292e03 100644 --- a/CoderMind/templates/commands/encode.md +++ b/CoderMind/templates/commands/encode.md @@ -1,5 +1,5 @@ --- -name: rpgkit.encode +name: cmind.encode description: Encode a repository into an RPG (Repository Program Graph) --- @@ -23,7 +23,7 @@ code entities) and edges (dependencies, containment). Run the check script to determine the current encode state: ```bash -rpgkit script rpg_encoder/check_encode.py --json +cmind script rpg_encoder/check_encode.py --json ``` Inspect the `type` field in the output: @@ -31,7 +31,7 @@ Inspect the `type` field in the output: **If type is "error"**: * Display the error message and stop. The RPG file may be corrupted. -* Suggest deleting the invalid file and re-running `/rpgkit.encode`. +* Suggest deleting the invalid file and re-running `/cmind.encode`. **If type is "init"**: @@ -49,12 +49,12 @@ Inspect the `type` field in the output: Choose an action: - R: Full re-encode (rebuild RPG from scratch) - - U: Incremental update (use /rpgkit.update_rpg instead) + - U: Incremental update (use /cmind.update_rpg instead) - Q: Quit ``` * If user chooses **R**: proceed to Step 2. -* If user chooses **U**: instruct user to run `/rpgkit.update_rpg` instead. Terminate. +* If user chooses **U**: instruct user to run `/cmind.update_rpg` instead. Terminate. * If user chooses **Q**: terminate. ### Step 2: Full Encode @@ -62,7 +62,7 @@ Inspect the `type` field in the output: Run the full encode script: ```bash -rpgkit script rpg_encoder/run_encode.py --json +cmind script rpg_encoder/run_encode.py --json ``` This may take several minutes depending on repository size and LLM response times. @@ -96,8 +96,8 @@ Display suggestions for what the user can do next: ```text Next steps: - - /rpgkit.update_rpg — Incrementally update after code changes + - /cmind.update_rpg — Incrementally update after code changes - The MCP server exposes search_rpg and explore_rpg tools for AI agents to query the RPG interactively. - - RPG data is saved at .rpgkit/data/rpg.json + - RPG data is saved at .cmind/data/rpg.json ``` diff --git a/CoderMind/templates/commands/feature_build.md b/CoderMind/templates/commands/feature_build.md index c035fe6..765b79e 100644 --- a/CoderMind/templates/commands/feature_build.md +++ b/CoderMind/templates/commands/feature_build.md @@ -1,6 +1,6 @@ --- description: Generate and iteratively refine the feature tree based on functional requirements. -name: rpgkit.feature_build +name: cmind.feature_build --- ## Workflow @@ -19,7 +19,7 @@ This workflow has four steps: Execute the following command to check the current state of input/output files: ```bash -rpgkit script feature_build_validation.py +cmind script feature_build_validation.py ``` **After execution, parse the JSON output and display a user-friendly summary.** @@ -30,14 +30,14 @@ rpgkit script feature_build_validation.py - Inform the user about the issues based on the error information in the output - - Remind the user to run `/rpgkit.feature_spec` first to create a valid `.rpgkit/data/feature_spec.json` + - Remind the user to run `/cmind.feature_spec` first to create a valid `.cmind/data/feature_spec.json` 2. **If `status` is `ready`:** 1. If message = "Output exists", display the following information for user decision: ```markdown - Output file `.rpgkit/data/feature_build.json` already exists. + Output file `.cmind/data/feature_build.json` already exists. Continuing will expand the feature tree beyond the specification, adding features not described in the spec but practically necessary for production use. Please enter your choice: @@ -61,7 +61,7 @@ The script automatically detects whether the output file (`feature_build.json`) 1. **Execute the command:** ```bash - rpgkit script feature_build.py --mode step1 + cmind script feature_build.py --mode step1 ``` The script prints its full output on stdout and also writes a @@ -115,7 +115,7 @@ After the spec-driven build is complete, ask the user whether they want to expan a. **Get expansion direction suggestions:** ```bash - rpgkit script feature_build.py --mode suggest-directions + cmind script feature_build.py --mode suggest-directions ``` The JSON payload is printed on stdout (and the full log is @@ -148,7 +148,7 @@ After the spec-driven build is complete, ask the user whether they want to expan Then pass the normalized indices to the script: ```bash - rpgkit script feature_build.py \ + cmind script feature_build.py \ --mode step2 \ --direction "" ``` @@ -156,7 +156,7 @@ After the spec-driven build is complete, ask the user whether they want to expan For example, if the user enters `1,3,5`: ```bash - rpgkit script feature_build.py \ + cmind script feature_build.py \ --mode step2 \ --direction "1,3,5" ``` @@ -201,4 +201,4 @@ Report includes: - Feature tree generation status - Total feature count -- Whether ready to proceed to the next phase (`/rpgkit.feature_refactor`) +- Whether ready to proceed to the next phase (`/cmind.feature_refactor`) diff --git a/CoderMind/templates/commands/feature_edit.md b/CoderMind/templates/commands/feature_edit.md index 54640d8..7ac3971 100644 --- a/CoderMind/templates/commands/feature_edit.md +++ b/CoderMind/templates/commands/feature_edit.md @@ -1,6 +1,6 @@ --- description: Edit the feature tree, nodes can be deleted, modified, added, or expanded as needed. -name: rpgkit.feature_edit +name: cmind.feature_edit --- @@ -22,13 +22,13 @@ If the input is empty, respond immediately: > - "Expand the 'security' component with more encryption options" > - "Merge 'analytics telemetry' into 'monitoring observability'" > -> Usage: `/rpgkit.feature_edit ` +> Usage: `/cmind.feature_edit ` ## Workflow -The text typed by the user after `/rpgkit.feature_edit` **is the edit instruction**. You can assume it is always available as `$ARGUMENTS`, unless explicitly empty. Do **not** ask the user to repeat it otherwise. +The text typed by the user after `/cmind.feature_edit` **is the edit instruction**. You can assume it is always available as `$ARGUMENTS`, unless explicitly empty. Do **not** ask the user to repeat it otherwise. -**File:** `.rpgkit/data/feature_tree.json` (both input and output) +**File:** `.cmind/data/feature_tree.json` (both input and output) **Working Directory**: All relative paths are based on the project root directory. @@ -37,7 +37,7 @@ The text typed by the user after `/rpgkit.feature_edit` **is the edit instructio Execute from repository root: ```bash -rpgkit script feature_edit_validation.py --edit_instruction "$ARGUMENTS" +cmind script feature_edit_validation.py --edit_instruction "$ARGUMENTS" ``` **Important:** If `$ARGUMENTS` contains a double quote (`"`), it MUST be escaped before being passed to the script. @@ -51,9 +51,9 @@ Inspect the `type` field in the output: - `file_not_found`: ```markdown - > **Error**: The file `.rpgkit/data/feature_tree.json` does not exist. + > **Error**: The file `.cmind/data/feature_tree.json` does not exist. > - > Please run `/rpgkit.feature_refactor` first to generate the feature tree. + > Please run `/cmind.feature_refactor` first to generate the feature tree. ``` - `field_empty` or `field_missing`: @@ -61,7 +61,7 @@ Inspect the `type` field in the output: ```markdown > **Error**: The file exists but the `components` field is missing or empty. > - > Please run `/rpgkit.feature_refactor` to generate a valid feature tree structure. + > Please run `/cmind.feature_refactor` to generate a valid feature tree structure. ``` 2. **If `type` is `"ready"`**: Proceed to Step 2. @@ -73,9 +73,9 @@ Inspect the `type` field in the output: Display the following prompt and wait for user confirmation: ```markdown -The script `rpgkit script feature_edit.py` will be executed to edit the feature tree based on your instructions. +The script `cmind script feature_edit.py` will be executed to edit the feature tree based on your instructions. -**File:** `.rpgkit/data/feature_tree.json` +**File:** `.cmind/data/feature_tree.json` **Edit Instructions:** > $ARGUMENTS @@ -96,7 +96,7 @@ Please confirm to proceed: Execute the following command: ```bash -rpgkit script feature_edit.py +cmind script feature_edit.py ``` The script writes a structured log automatically; stdout @@ -120,18 +120,18 @@ After the script completes: ```markdown **Edit Complete** - The edited feature tree has been saved to `.rpgkit/data/feature_tree.json`. + The edited feature tree has been saved to `.cmind/data/feature_tree.json`. Please review the changes to verify they match your expectations. If further adjustments are needed, run: ```text - /rpgkit.feature_edit + /cmind.feature_edit ``` If you are satisfied with the feature tree and ready to proceed to the **next step**, run: ```text - /rpgkit.build_skeleton + /cmind.build_skeleton ``` diff --git a/CoderMind/templates/commands/feature_refactor.md b/CoderMind/templates/commands/feature_refactor.md index c307798..371c7e8 100644 --- a/CoderMind/templates/commands/feature_refactor.md +++ b/CoderMind/templates/commands/feature_refactor.md @@ -1,6 +1,6 @@ --- description: Refactor feature tree into modular component architecture -name: rpgkit.feature_refactor +name: cmind.feature_refactor --- ## Workflow @@ -10,19 +10,19 @@ name: rpgkit.feature_refactor 1. Run the validation script to verify input and check output file status: ```bash - rpgkit script feature_refactor_validation.py + cmind script feature_refactor_validation.py ``` The script outputs a JSON object. Determine the next action based on the `status` and `action` fields: - 1. **If `status` is `"error"`**: The input file `.rpgkit/data/feature_build.json` is missing or invalid. Display the error message, prompt the user to rerun the `/rpgkit.feature_build` command, and then exit. + 1. **If `status` is `"error"`**: The input file `.cmind/data/feature_build.json` is missing or invalid. Display the error message, prompt the user to rerun the `/cmind.feature_build` command, and then exit. 2. **If `status` is `"ready"` and `action` is `"create"`**: The output file does not exist or has no valid content. Proceed directly to the next step. 3. **If `status` is `"ready"` and `action` is `"overwrite_or_skip"`**: The output file already exists with content. Display the following prompt and wait for user confirmation: ```markdown - Note: The output file `.rpgkit/data/feature_tree.json` already exists and is not empty. Please confirm the operation: + Note: The output file `.cmind/data/feature_tree.json` already exists and is not empty. Please confirm the operation: - **Y**: Regenerate the feature tree and overwrite the existing output file. - **N**: Cancel and exit the agent. @@ -33,7 +33,7 @@ name: rpgkit.feature_refactor 1. Must display the following information and prompt the user to confirm the maximum number of iterations (default: 10). ```markdown - **description**: Run the script `rpgkit script feature_refactor.py` to perform a two-step process: + **description**: Run the script `cmind script feature_refactor.py` to perform a two-step process: - Step 1: Plan the structure and number of subtrees - Step 2: Iteratively assign features to the planned subtrees @@ -47,7 +47,7 @@ name: rpgkit.feature_refactor 2. Execute the following command with the selected max iteration count (default: 10 or user-defined): ```bash - rpgkit script feature_refactor.py --max-iterations + cmind script feature_refactor.py --max-iterations ``` The script writes a structured log automatically; @@ -55,22 +55,22 @@ name: rpgkit.feature_refactor 3. Analyze and summarize the information printed during script execution, and present the results in a Markdown table format. -3. Prompt the user to review the output file `.rpgkit/data/feature_tree.json`, paying particular attention to the `components` field, which represents the final feature tree. +3. Prompt the user to review the output file `.cmind/data/feature_tree.json`, paying particular attention to the `components` field, which represents the final feature tree. - If the user determines that **minor adjustments** are needed, instruct them to run: ```text - /rpgkit.feature_edit + /cmind.feature_edit ``` - If the user wants to **regenerate the entire feature tree**, instruct them to run: ```text - /rpgkit.feature_refactor + /cmind.feature_refactor ``` - If the user is satisfied and wants to proceed to the **next step**, instruct them to run: ```text - /rpgkit.build_skeleton + /cmind.build_skeleton ``` diff --git a/CoderMind/templates/commands/feature_spec.md b/CoderMind/templates/commands/feature_spec.md index 7003848..853016c 100644 --- a/CoderMind/templates/commands/feature_spec.md +++ b/CoderMind/templates/commands/feature_spec.md @@ -1,6 +1,6 @@ --- description: Create structured feature specifications from user input or documentation files -name: rpgkit.feature_spec +name: cmind.feature_spec --- ## User Input @@ -9,7 +9,7 @@ name: rpgkit.feature_spec $ARGUMENTS ``` -Text provided after `/rpgkit.feature_spec` will be used as the feature description. If empty, the agent will automatically detect and use files in the `docs/` directory. +Text provided after `/cmind.feature_spec` will be used as the feature description. If empty, the agent will automatically detect and use files in the `docs/` directory. ## Capabilities @@ -22,7 +22,7 @@ Text provided after `/rpgkit.feature_spec` will be used as the feature descripti ## Output Directory Structure ```text -.rpgkit/data/feature_spec/ +.cmind/data/feature_spec/ ├── evidence/ # Step 2 output │ ├── user_input.md # (from user input) or │ ├── 01_project_charter.md # (from docs/) @@ -50,7 +50,7 @@ If `$ARGUMENTS` is **not empty**: - **Mode**: User-provided description - **Input Length**: characters -- **Output Directory**: .rpgkit/data/feature_spec/ +- **Output Directory**: .cmind/data/feature_spec/ Processing user-provided feature description. ``` @@ -93,13 +93,13 @@ The feature specification process requires one of the following: 1. **Provide a feature description as input:** - `/rpgkit.feature_spec ` + `/cmind.feature_spec ` 2. **Place documentation files in the `docs/` directory:** Add requirement or design documents to the `docs/` directory, then run: - `/rpgkit.feature_spec` + `/cmind.feature_spec` ``` → **Terminate agent execution** @@ -126,7 +126,7 @@ Convert user input to Evidence file format. #### 2A.2: Generate Evidence File -Create `.rpgkit/data/feature_spec/evidence/user_input.md`: +Create `.cmind/data/feature_spec/evidence/user_input.md`: ```markdown # Evidence: user_input.md @@ -163,7 +163,7 @@ Create `.rpgkit/data/feature_spec/evidence/user_input.md`: ```markdown ## ✓ User Input Processing Complete -- **Evidence File**: .rpgkit/data/feature_spec/evidence/user_input.md +- **Evidence File**: .cmind/data/feature_spec/evidence/user_input.md - **Background Entries**: - **FR Entries**: - **NFR Entries**: @@ -285,7 +285,7 @@ Project risks, external risks, operational processes, inter-document references, #### 2B.4: **Generate Evidence Files** -For each document, create `.rpgkit/data/feature_spec/evidence/{document_name}.md`: +For each document, create `.cmind/data/feature_spec/evidence/{document_name}.md`: ```markdown # Evidence: {document_name}.md @@ -330,11 +330,11 @@ After processing each document: ## Document Processing Progress ### ✓ .md -- **Evidence File**: .rpgkit/data/feature_spec/evidence/.md +- **Evidence File**: .cmind/data/feature_spec/evidence/.md - **Background**: | **FR**: | **NFR**: ### ✓ .md -- **Evidence File**: .rpgkit/data/feature_spec/evidence/.md +- **Evidence File**: .cmind/data/feature_spec/evidence/.md - **Background**: | **FR**: | **NFR**: ... @@ -355,7 +355,7 @@ Generate the main feature specification file containing Meta, Background, and NF #### 3.1: Read All Evidence Files -Load all `.md` files from `.rpgkit/data/feature_spec/evidence/`. +Load all `.md` files from `.cmind/data/feature_spec/evidence/`. #### 3.2: Determine Repository Information @@ -405,7 +405,7 @@ Derive from evidence: #### 3.5: Generate feature_spec.md -Create `.rpgkit/data/feature_spec/feature_spec.md`: +Create `.cmind/data/feature_spec/feature_spec.md`: ```markdown # Feature Specification @@ -449,7 +449,7 @@ Create `.rpgkit/data/feature_spec/feature_spec.md`: ```markdown ## ✓ Main File Generation Complete -- **Output File**: .rpgkit/data/feature_spec/feature_spec.md +- **Output File**: .cmind/data/feature_spec/feature_spec.md - **Repository Name**: {name} - **Background Entries**: - **NFR Entries**: @@ -499,7 +499,7 @@ Read original excerpts from all FR evidence and cluster by feature semantics: #### 4.3: Generate Feature Files -For each domain, create `.rpgkit/data/feature_spec/features/FT-{NNN}.md`: +For each domain, create `.cmind/data/feature_spec/features/FT-{NNN}.md`: ```markdown # FT-001: {Domain Name} @@ -607,7 +607,7 @@ Convert generated Markdown feature specification files to JSON format. Execute the following command: ```bash -rpgkit script feature_spec_to_json.py +cmind script feature_spec_to_json.py ``` #### 5.2: Verify Output @@ -615,10 +615,10 @@ rpgkit script feature_spec_to_json.py Confirm conversion results based on script log output. The script will output logs in a format similar to: ```text -Parsing feature specification from: .rpgkit/data/feature_spec +Parsing feature specification from: .cmind/data/feature_spec Include evidence: True -Output written to: .rpgkit/data/feature_spec.json +Output written to: .cmind/data/feature_spec.json - Repository: {name} - Background items: - NFR items: @@ -631,7 +631,7 @@ Display results based on log information: ```markdown ## ✓ JSON Conversion Complete -- **Output File**: .rpgkit/data/feature_spec.json +- **Output File**: .cmind/data/feature_spec.json - **Repository**: {from log} - **Background Entries**: {from log} - **NFR Entries**: {from log} @@ -654,10 +654,10 @@ Display results based on log information: | File | Description | |------|-------------| -| .rpgkit/data/feature_spec/evidence/*.md | Evidence files | -| .rpgkit/data/feature_spec/feature_spec.md | Main specification file | -| .rpgkit/data/feature_spec/features/FT-*.md | Feature domain files | -| .rpgkit/data/feature_spec.json | JSON format specification file | +| .cmind/data/feature_spec/evidence/*.md | Evidence files | +| .cmind/data/feature_spec/feature_spec.md | Main specification file | +| .cmind/data/feature_spec/features/FT-*.md | Feature domain files | +| .cmind/data/feature_spec.json | JSON format specification file | ### Statistics @@ -674,7 +674,7 @@ Display results based on log information: To expand and build the feature tree, run: -`/rpgkit.feature_build` +`/cmind.feature_build` ``` --- diff --git a/CoderMind/templates/commands/plan_tasks.md b/CoderMind/templates/commands/plan_tasks.md index 3b1634b..7597c3b 100644 --- a/CoderMind/templates/commands/plan_tasks.md +++ b/CoderMind/templates/commands/plan_tasks.md @@ -1,5 +1,5 @@ --- -name: rpgkit.plan_tasks +name: cmind.plan_tasks description: Plan implementation tasks from interface definitions --- @@ -14,7 +14,7 @@ Create implementation tasks from the interface definitions. Run the check script to determine current state: ```bash -rpgkit script check_tasks.py --json +cmind script check_tasks.py --json ``` **If type is "error"**: @@ -60,7 +60,7 @@ rpgkit script check_tasks.py --json Run the task planner: ```bash -rpgkit script plan_tasks.py +cmind script plan_tasks.py ``` The script writes a structured log automatically; stdout carries the @@ -74,14 +74,14 @@ This will: 4. Group into implementation tasks 5. **Append the main entry point task** (main.py) as the final core task 6. **Append project file tasks** (requirements.txt, README.md) as post-implementation tasks -7. Save the ordered tasks to `.rpgkit/data/tasks.json` +7. Save the ordered tasks to `.cmind/data/tasks.json` ### Step 3: Validation After generation, run the check script again: ```bash -rpgkit script check_tasks.py --json +cmind script check_tasks.py --json ``` Verify: diff --git a/CoderMind/templates/commands/rpg_edit.md b/CoderMind/templates/commands/rpg_edit.md index 6f5186b..bb8550f 100644 --- a/CoderMind/templates/commands/rpg_edit.md +++ b/CoderMind/templates/commands/rpg_edit.md @@ -1,6 +1,6 @@ --- description: Edit RPG feature graph + code + dep_graph in sync, driven by natural language. -name: rpgkit.rpg_edit +name: cmind.rpg_edit --- ## User Input @@ -20,28 +20,28 @@ If the input is empty, respond immediately: > - "Add rate limiting (10 req/s) to all API endpoints" > - "Refactor the auth module, split registration and login into separate files" > -> Usage: `/rpgkit.rpg_edit ` +> Usage: `/cmind.rpg_edit ` ## Overview -`/rpgkit.rpg_edit` is an **independent command** that uses the RPG feature +`/cmind.rpg_edit` is an **independent command** that uses the RPG feature graph as the entry point to locate modification targets, then drives synchronized changes across **code + RPG + dep_graph**. - Does NOT go through `feature_tree.json`. -- Does NOT depend on `/rpgkit.feature_edit` or `/rpgkit.update_rpg`. +- Does NOT depend on `/cmind.feature_edit` or `/cmind.update_rpg`. - The RPG feature graph is the authoritative source for code modifications. ## Workflow -The text after `/rpgkit.rpg_edit` is the edit instruction, available as `$ARGUMENTS`. +The text after `/cmind.rpg_edit` is the edit instruction, available as `$ARGUMENTS`. **Working Directory**: All relative paths are based on the project root. ### Step 1: Pre-check ```bash -rpgkit script rpg_edit/validate.py --json +cmind script rpg_edit/validate.py --json ``` Inspect the `type` field: @@ -52,7 +52,7 @@ Inspect the `type` field: ### Step 2: Locate Target Nodes ```bash -rpgkit script rpg_edit/locate.py --query "$ARGUMENTS" --json +cmind script rpg_edit/locate.py --query "$ARGUMENTS" --json ``` > **Note:** If `$ARGUMENTS` contains double quotes, escape them before passing. @@ -79,7 +79,7 @@ For each selected node, run impact analysis and persist the result so the Step 5d review step can pick it up automatically: ```bash -rpgkit script rpg_edit/impact.py --node-id [--node-id ...] --json --save +cmind script rpg_edit/impact.py --node-id [--node-id ...] --json --save ``` The `--save` flag persists `rpg_edit_impact.json` for downstream stages; @@ -107,7 +107,7 @@ If no keyword matches, skip directly to Step 4. **Step 3.5a — Probe tool availability (≤ 5s):** ```bash -rpgkit script tools/browser.py check >/dev/null 2>&1 \ +cmind script tools/browser.py check >/dev/null 2>&1 \ && BROWSER_OK=1 || BROWSER_OK=0 ``` @@ -129,7 +129,7 @@ Step 4. **Step 3.5c — Run inspect:** ```bash -rpgkit script tools/browser.py inspect +cmind script tools/browser.py inspect ``` The command prints paths to the saved HTML and screenshot. Read the @@ -164,7 +164,7 @@ assumptions from node names. Poor plans come from skipping this step. was skipped but the app is running, take a screenshot now: ```bash - rpgkit script tools/browser.py inspect http://localhost:/ + cmind script tools/browser.py inspect http://localhost:/ ``` 4. **Collect all files that need changes** — not just the ones from @@ -202,10 +202,10 @@ in `code_changes`: Save the plan via the dedicated helper, which persists `rpg_edit_plan.json` for downstream stages and prints the absolute -path on stdout. Do NOT use the Write tool for `.rpgkit/` paths: +path on stdout. Do NOT use the Write tool for `.cmind/` paths: ```bash -cat << 'PLAN_EOF' | rpgkit script rpg_edit/save_plan.py +cat << 'PLAN_EOF' | cmind script rpg_edit/save_plan.py PLAN_EOF ``` @@ -268,7 +268,7 @@ do **not** silently `git stash`, as that would hide their work. **Step 5b — Update RPG feature graph:** ```bash -rpgkit script rpg_edit/apply.py --phase rpg-only --json +cmind script rpg_edit/apply.py --phase rpg-only --json ``` This applies `feature_changes` to the RPG and saves it (reading the plan @@ -283,7 +283,7 @@ mode, and the driver script creates a single commit on the current branch (even when multiple SubAgent iterations are needed). ```bash -rpgkit script rpg_edit/code.py --json +cmind script rpg_edit/code.py --json ``` Inspect the result `success` field: @@ -299,7 +299,7 @@ If success, refresh the dep_graph and amend the existing commit so that code + dep_graph land together: ```bash -rpgkit script rpg_edit/apply.py --phase dep-refresh \ +cmind script rpg_edit/apply.py --phase dep-refresh \ --backup-ts --json git add -A && git commit --amend --no-edit @@ -310,13 +310,13 @@ git add -A && git commit --amend --no-edit 1. **Smoke test** — verify imports and entry point: ```bash -rpgkit script smoke_test.py --json +cmind script smoke_test.py --json ``` 1. **Impact review** — run targeted tests and verify affected functionality: ```bash -rpgkit script rpg_edit/review.py --json +cmind script rpg_edit/review.py --json ``` The review script reads the plan and impact JSON from their default @@ -357,7 +357,7 @@ visible in `git log --graph`. > Merged `rpg-edit/` into `main` (commit ``). > To revert later: > - Code: `git revert -m 1 ` - > - Graphs: `rpgkit script rpg_edit/apply.py --rollback --json` + > - Graphs: `cmind script rpg_edit/apply.py --rollback --json` If the review output contained `suggestions`, append: @@ -365,7 +365,7 @@ visible in `git log --graph`. > - > - > - > You can address these with another `/rpgkit.rpg_edit` command. + > You can address these with another `/cmind.rpg_edit` command. - **Failure path** (Step 5d failed, Step 5e skipped): @@ -381,7 +381,7 @@ visible in `git log --graph`. > `main` is clean. Choose one of: > - Inspect: `git diff main rpg-edit/` > - Discard code + graphs together: - > `rpgkit script rpg_edit/apply.py --rollback --rollback-branch rpg-edit/ --json` + > `cmind script rpg_edit/apply.py --rollback --rollback-branch rpg-edit/ --json` > - Discard code only: `git branch -D rpg-edit/` > - Continue editing on the branch and re-run from Step 5d. @@ -392,4 +392,4 @@ visible in `git log --graph`. 3. **User confirmation** — always confirm the plan before applying changes. Never auto-apply. 4. **Branch isolation** — `main` is touched only after tests pass. Failed runs leave the work on a `rpg-edit/` branch for inspection. 5. **Coordinated rollback** — `--rollback --rollback-branch ` reverts RPG, dep_graph, and the dedicated branch in one step. -6. **Independent command** — does not depend on or invoke any other `/rpgkit.*` command. +6. **Independent command** — does not depend on or invoke any other `/cmind.*` command. diff --git a/CoderMind/templates/commands/update_rpg.md b/CoderMind/templates/commands/update_rpg.md index 2cf34b2..edfc78d 100644 --- a/CoderMind/templates/commands/update_rpg.md +++ b/CoderMind/templates/commands/update_rpg.md @@ -1,5 +1,5 @@ --- -name: rpgkit.update_rpg +name: cmind.update_rpg description: Manually trigger an incremental RPG update (fallback for when the post-commit hook didn't run) --- @@ -23,7 +23,7 @@ automatic update didn't happen, e.g.: * You committed with `git commit --no-verify` (skipping hooks). * The background hook errored out (network blip, LLM timeout) — run - `rpgkit version` to locate the workspace's logs directory and tail + `cmind version` to locate the workspace's logs directory and tail the latest `update_rpg.log` there. * You want to force a fresh update synchronously and see the result immediately instead of waiting for the async hook. @@ -36,14 +36,14 @@ uses) and runs the LLM-driven feature graph diff + dep_graph rebuild. Run the check script: ```bash -rpgkit script rpg_encoder/check_encode.py --json +cmind script rpg_encoder/check_encode.py --json ``` Inspect the `type` field in the JSON output: * **`error`** → display `message` and stop. The `rpg.json` file is - corrupt; the user may need to delete it and rerun `/rpgkit.encode`. -* **`init`** → no `rpg.json` yet. Tell the user to run `/rpgkit.encode` + corrupt; the user may need to delete it and rerun `/cmind.encode`. +* **`init`** → no `rpg.json` yet. Tell the user to run `/cmind.encode` first to create the baseline graph, then terminate. * **`update`** → display `result.stats.repo_name` / `node_count` / `edge_count` and proceed to Step 2. @@ -56,7 +56,7 @@ git rev-list --count HEAD ``` If the count is `< 2`, tell the user there is no previous commit to -diff against, and suggest running `/rpgkit.encode` instead. Terminate. +diff against, and suggest running `/cmind.encode` instead. Terminate. ### Step 2: Run the Update @@ -65,7 +65,7 @@ up its own temporary worktree internally — **you do not need to manage `git worktree` manually**. ```bash -rpgkit script update_graphs.py update-rpg --json +cmind script update_graphs.py update-rpg --json ``` The full JSON result is printed on stdout (single `{...}` block). The @@ -90,7 +90,7 @@ RPG update complete! **If `status` is `"error"`**: * Show the `error` field. -* Tell the user to run `rpgkit version` to locate the logs directory +* Tell the user to run `cmind version` to locate the logs directory and inspect `update_rpg.log` for the full trace. * Common causes: LLM API misconfigured, network failure, dirty worktree blocking `git worktree add`. @@ -102,8 +102,8 @@ Tips: - The post-commit hook runs this same update automatically after every commit; you only need to invoke this command when the automatic update failed or was skipped. - - /rpgkit.encode — Run a full re-encode if the RPG seems stale or + - /cmind.encode — Run a full re-encode if the RPG seems stale or has drifted significantly from the codebase. - - The latest `update_rpg.log` (path shown by `rpgkit version`) keeps + - The latest `update_rpg.log` (path shown by `cmind version`) keeps the most recent run output. ``` diff --git a/CoderMind/tests/fixtures/sample_repo/README.md b/CoderMind/tests/fixtures/sample_repo/README.md index 74801f4..39b0792 100644 --- a/CoderMind/tests/fixtures/sample_repo/README.md +++ b/CoderMind/tests/fixtures/sample_repo/README.md @@ -1,4 +1,4 @@ # Sample Repo -A minimal test repository for RPG-Kit E2E testing. +A minimal test repository for CoderMind E2E testing. Contains a simple user management module with models and utilities. diff --git a/CoderMind/tests/test_dep_graph_incremental.py b/CoderMind/tests/test_dep_graph_incremental.py index 0c8879f..5554b32 100644 --- a/CoderMind/tests/test_dep_graph_incremental.py +++ b/CoderMind/tests/test_dep_graph_incremental.py @@ -11,7 +11,7 @@ Anything weaker risks silent drift between incremental and full updates, which would mean the pre-commit hook (Step 3) and the codegen path (Step 4) gradually corrupt the graph in ways nobody notices until a -``/rpgkit.update_rpg`` full rebuild reveals the discrepancy. +``/cmind.update_rpg`` full rebuild reveals the discrepancy. We use small synthetic repos because the equivalence check is O(nodes + edges) and we want sub-second tests. The cross-file semantic-edge diff --git a/CoderMind/tests/test_e2e.py b/CoderMind/tests/test_e2e.py index da3bda0..18e0c0f 100644 --- a/CoderMind/tests/test_e2e.py +++ b/CoderMind/tests/test_e2e.py @@ -168,9 +168,9 @@ def sample_repo(tmp_path): @pytest.fixture -def rpgkit_dir(tmp_path): - """Create a temporary .rpgkit directory.""" - d = tmp_path / ".rpgkit" +def cmind_dir(tmp_path): + """Create a temporary .cmind directory.""" + d = tmp_path / ".cmind" d.mkdir() return str(d) @@ -594,7 +594,7 @@ def test_incremental_update_cycle(self, encoded_rpg): class TestE2EFullPipeline: """Test the complete encode -> search -> update -> search cycle.""" - def test_full_encode_search_update_cycle(self, encoded_rpg, rpgkit_dir): + def test_full_encode_search_update_cycle(self, encoded_rpg, cmind_dir): """Complete lifecycle test: encode, search, update, save, load.""" rpg = encoded_rpg @@ -642,14 +642,14 @@ def log_error(self, user_id: int, error: str): # Phase 5: Save the RPG save_result = WorkflowIntegration.save_rpg( rpg=rpg, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, message="E2E test save after update", source="mixed", ) assert os.path.isfile(save_result["rpg_path"]) # Phase 6: Load and verify - loaded = WorkflowIntegration.load_rpg(rpgkit_dir) + loaded = WorkflowIntegration.load_rpg(cmind_dir) assert loaded is not None assert loaded.repo_name == "sample_repo" @@ -662,7 +662,7 @@ def log_error(self, user_id: int, error: str): assert context["repo_name"] == "sample_repo" assert "existing_interfaces" in context - def test_multi_step_evolution(self, encoded_rpg, rpgkit_dir): + def test_multi_step_evolution(self, encoded_rpg, cmind_dir): """Multiple sequential updates maintain RPG consistency.""" rpg = encoded_rpg @@ -711,10 +711,10 @@ def send_sms(to: str, message: str): # Save and verify save_result = WorkflowIntegration.save_rpg( - rpg=rpg, rpgkit_dir=rpgkit_dir, + rpg=rpg, cmind_dir=cmind_dir, message="Multi-step evolution", source="mixed", ) - loaded = WorkflowIntegration.load_rpg(rpgkit_dir) + loaded = WorkflowIntegration.load_rpg(cmind_dir) assert loaded.find_node_by_path("src/payment.py") is not None assert loaded.find_node_by_path("src/notification.py") is not None assert loaded.find_node_by_path("src/utils/helpers.py") is None @@ -773,12 +773,12 @@ def test_mcp_query_engine_with_real_rpg(self, encoded_rpg, sample_repo, tmp_path # ============================================================================ -# 6. Compatibility: existing RPG-Kit features unaffected +# 6. Compatibility: existing CoderMind features unaffected # ============================================================================ class TestCompatibility: - """Verify that existing RPG-Kit functionality works alongside encoder.""" + """Verify that existing CoderMind functionality works alongside encoder.""" def test_rpg_basic_operations(self): """Basic RPG operations (add node, add edge, to_dict) still work. diff --git a/CoderMind/tests/test_encode_commands.py b/CoderMind/tests/test_encode_commands.py index a59a1f9..f05b9fe 100644 --- a/CoderMind/tests/test_encode_commands.py +++ b/CoderMind/tests/test_encode_commands.py @@ -108,9 +108,9 @@ def test_init_state_no_rpg_file(self, tmp_path, monkeypatch): def test_update_state_valid_rpg(self, tmp_path, monkeypatch): """When a valid rpg.json exists, check_encode should return type=update.""" monkeypatch.chdir(tmp_path) - rpgkit_data = tmp_path / ".rpgkit" / "data" - rpgkit_data.mkdir(parents=True) - rpg_file = rpgkit_data / "rpg.json" + cmind_data = tmp_path / ".cmind" / "data" + cmind_data.mkdir(parents=True) + rpg_file = cmind_data / "rpg.json" rpg_file.write_text(json.dumps(_make_rpg_data(), indent=2)) from rpg_encoder.check_encode import check_encode @@ -124,9 +124,9 @@ def test_update_state_valid_rpg(self, tmp_path, monkeypatch): def test_error_state_invalid_rpg(self, tmp_path, monkeypatch): """When rpg.json exists but has invalid format, return type=error.""" monkeypatch.chdir(tmp_path) - rpgkit_data = tmp_path / ".rpgkit" / "data" - rpgkit_data.mkdir(parents=True) - rpg_file = rpgkit_data / "rpg.json" + cmind_data = tmp_path / ".cmind" / "data" + cmind_data.mkdir(parents=True) + rpg_file = cmind_data / "rpg.json" rpg_file.write_text(json.dumps({"some_key": "value"}, indent=2)) from rpg_encoder.check_encode import check_encode @@ -137,9 +137,9 @@ def test_error_state_invalid_rpg(self, tmp_path, monkeypatch): def test_error_state_empty_file(self, tmp_path, monkeypatch): """When rpg.json exists but is empty, return type=error.""" monkeypatch.chdir(tmp_path) - rpgkit_data = tmp_path / ".rpgkit" / "data" - rpgkit_data.mkdir(parents=True) - rpg_file = rpgkit_data / "rpg.json" + cmind_data = tmp_path / ".cmind" / "data" + cmind_data.mkdir(parents=True) + rpg_file = cmind_data / "rpg.json" rpg_file.write_text("") from rpg_encoder.check_encode import check_encode @@ -149,9 +149,9 @@ def test_error_state_empty_file(self, tmp_path, monkeypatch): def test_update_state_nested_format(self, tmp_path, monkeypatch): """When rpg.json uses nested rpg.structure format, return type=update.""" monkeypatch.chdir(tmp_path) - rpgkit_data = tmp_path / ".rpgkit" / "data" - rpgkit_data.mkdir(parents=True) - rpg_file = rpgkit_data / "rpg.json" + cmind_data = tmp_path / ".cmind" / "data" + cmind_data.mkdir(parents=True) + rpg_file = cmind_data / "rpg.json" nested_data = { "repo_name": "nested_repo", "rpg": { @@ -172,9 +172,9 @@ def test_update_state_nested_format(self, tmp_path, monkeypatch): def test_update_state_root_tree_format(self, tmp_path, monkeypatch): """When rpg.json uses root tree format (nested children), return type=update.""" monkeypatch.chdir(tmp_path) - rpgkit_data = tmp_path / ".rpgkit" / "data" - rpgkit_data.mkdir(parents=True) - rpg_file = rpgkit_data / "rpg.json" + cmind_data = tmp_path / ".cmind" / "data" + cmind_data.mkdir(parents=True) + rpg_file = cmind_data / "rpg.json" tree_data = { "repo_name": "tree_repo", "root": { @@ -327,13 +327,13 @@ def test_encode_template_frontmatter(self): encode_md = os.path.join(self._template_dir, "encode.md") fm = self._parse_frontmatter(encode_md) assert "name" in fm - assert fm["name"] == "rpgkit.encode" + assert fm["name"] == "cmind.encode" def test_update_rpg_template_frontmatter(self): update_md = os.path.join(self._template_dir, "update_rpg.md") fm = self._parse_frontmatter(update_md) assert "name" in fm - assert fm["name"] == "rpgkit.update_rpg" + assert fm["name"] == "cmind.update_rpg" def test_encode_template_references_check_script(self): encode_md = os.path.join(self._template_dir, "encode.md") @@ -498,7 +498,7 @@ def test_create_mcp_server_handles_missing_rpg_file(self, tmp_path): ``create_mcp_server`` surfaces on the MCP client as the opaque ``MCP error -32000: Connection closed`` and hides the real cause. The server is required to come up in degraded mode and the - ``_unavailable_payload`` helper must point users at ``/rpgkit.encode``. + ``_unavailable_payload`` helper must point users at ``/cmind.encode``. """ import mcp_server as m missing = tmp_path / "rpg.json" @@ -508,7 +508,7 @@ def test_create_mcp_server_handles_missing_rpg_file(self, tmp_path): assert server.name == "rpg-tools" payload = json.loads(m._unavailable_payload(str(missing), "file_not_found")) assert payload["error"] == "rpg_unavailable" - assert "/rpgkit.encode" in payload["next_step"] + assert "/cmind.encode" in payload["next_step"] # ============================================================================ @@ -518,19 +518,19 @@ def test_create_mcp_server_handles_missing_rpg_file(self, tmp_path): class TestCLIIntegration: def test_main_app_no_encode_command(self): """The main app should NOT have 'encode' registered (removed in M12 redo).""" - from rpgkit_cli import app + from cmind_cli import app command_names = [cmd.name for cmd in app.registered_commands] assert "encode" not in command_names def test_main_app_no_update_rpg_command(self): """The main app should NOT have 'update-rpg' registered.""" - from rpgkit_cli import app + from cmind_cli import app command_names = [cmd.name for cmd in app.registered_commands] assert "update-rpg" not in command_names def test_main_app_no_mcp_server_command(self): """The main app should NOT have 'mcp-server' registered.""" - from rpgkit_cli import app + from cmind_cli import app command_names = [cmd.name for cmd in app.registered_commands] assert "mcp-server" not in command_names diff --git a/CoderMind/tests/test_encoder_workspace_layout.py b/CoderMind/tests/test_encoder_workspace_layout.py index c5b0754..71a3ea7 100644 --- a/CoderMind/tests/test_encoder_workspace_layout.py +++ b/CoderMind/tests/test_encoder_workspace_layout.py @@ -4,7 +4,7 @@ The encoder entry points (``run_encode.py`` / ``run_update_rpg.py``) and the ``update_graphs.py sync`` hook all default to scanning :data:`common.paths.WORKSPACE_ROOT` — the -directory the user ran ``rpgkit init --here`` in (their existing +directory the user ran ``cmind init --here`` in (their existing source repository). There is no ``repo/`` sub-convention to honour on the encoder side; the decoder pipeline writes code to ``REPO_DIR`` through entirely separate entry points. @@ -39,7 +39,7 @@ def _reload_paths_against(workspace: Path): layouts we must reload after chdir'ing. """ os.chdir(workspace) - os.environ.pop("RPGKIT_WORKSPACE", None) + os.environ.pop("CMIND_WORKSPACE", None) import common.paths as paths_mod importlib.reload(paths_mod) return paths_mod @@ -47,14 +47,14 @@ def _reload_paths_against(workspace: Path): @pytest.fixture def encoder_workspace(tmp_path, monkeypatch): - """A workspace with ``.rpgkit/`` but NO ``repo/`` subdirectory — the canonical encoder layout (``rpgkit init --here`` inside an existing code repository).""" + """A workspace with ``.cmind/`` but NO ``repo/`` subdirectory — the canonical encoder layout (``cmind init --here`` inside an existing code repository).""" ws = tmp_path / "enc_ws" ws.mkdir() - (ws / ".rpgkit").mkdir() + (ws / ".cmind").mkdir() (ws / "auth.py").write_text("def login(): pass\n") (ws / "db.py").write_text("def connect(): pass\n") monkeypatch.chdir(ws) - monkeypatch.delenv("RPGKIT_WORKSPACE", raising=False) + monkeypatch.delenv("CMIND_WORKSPACE", raising=False) return ws @@ -69,11 +69,11 @@ def workspace_with_repo_subdir(tmp_path, monkeypatch): """ ws = tmp_path / "ws_with_repo" ws.mkdir() - (ws / ".rpgkit").mkdir() + (ws / ".cmind").mkdir() (ws / "repo").mkdir() (ws / "repo" / "main.py").write_text("def main(): pass\n") monkeypatch.chdir(ws) - monkeypatch.delenv("RPGKIT_WORKSPACE", raising=False) + monkeypatch.delenv("CMIND_WORKSPACE", raising=False) return ws @@ -113,7 +113,7 @@ def test_run_update_rpg_error_path_in_encoder_layout(encoder_workspace): import rpg_encoder.run_update_rpg as upd importlib.reload(upd) - rpg_path = encoder_workspace / ".rpgkit" / "data" / "rpg.json" + rpg_path = encoder_workspace / ".cmind" / "data" / "rpg.json" rpg_path.parent.mkdir(parents=True, exist_ok=True) rpg_path.write_text('{"repo_name": "test", "root": {}}') @@ -167,7 +167,7 @@ def test_run_update_rpg_explicit_override_wins( explicit = tmp_path / "elsewhere" explicit.mkdir() (explicit / "x.py").write_text("x = 1\n") - rpg_path = workspace_with_repo_subdir / ".rpgkit" / "data" / "rpg.json" + rpg_path = workspace_with_repo_subdir / ".cmind" / "data" / "rpg.json" rpg_path.parent.mkdir(parents=True, exist_ok=True) rpg_path.write_text('{"repo_name": "test", "root": {}}') diff --git a/CoderMind/tests/test_hooks_install.py b/CoderMind/tests/test_hooks_install.py index 8a7110c..07cc95a 100644 --- a/CoderMind/tests/test_hooks_install.py +++ b/CoderMind/tests/test_hooks_install.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Tests for RPG-Kit hook installation (Claude SessionStart, Copilot folderOpen task, and git pre-commit) and the ``update_graphs.py status`` subcommand the hooks invoke. +"""Tests for CoderMind hook installation (Claude SessionStart, Copilot folderOpen task, and git pre-commit) and the ``update_graphs.py status`` subcommand the hooks invoke. Verifies: - ``_install_claude_hooks`` writes a SessionStart hook that calls @@ -28,7 +28,7 @@ sys.path.insert(0, str(_project_root / "src")) sys.path.insert(0, str(_project_root / "scripts")) -import rpgkit_cli # noqa: E402 +import cmind_cli # noqa: E402 # --------------------------------------------------------------------------- @@ -37,8 +37,8 @@ @pytest.fixture def project(tmp_path): - """A minimal RPG-Kit workspace with .rpgkit/scripts/update_graphs.py.""" - scripts_dir = tmp_path / ".rpgkit" / "scripts" + """A minimal CoderMind workspace with .cmind/scripts/update_graphs.py.""" + scripts_dir = tmp_path / ".cmind" / "scripts" scripts_dir.mkdir(parents=True) # The installers only need the file to exist; we copy the real script # so that subprocess invocations later in the test can actually run. @@ -55,42 +55,42 @@ def project(tmp_path): # --------------------------------------------------------------------------- def test_install_claude_hooks_writes_session_start(project): - rpgkit_cli._install_claude_hooks(project) + cmind_cli._install_claude_hooks(project) data = json.loads((project / ".claude" / "settings.json").read_text()) assert "hooks" in data session_start = data["hooks"]["SessionStart"] assert isinstance(session_start, list) and len(session_start) == 1 cmd = session_start[0]["hooks"][0]["command"] - # Hook now invokes the global ``rpgkit`` CLI; no embedded sys.executable. - assert "rpgkit script update_graphs.py status" in cmd + # Hook now invokes the global ``cmind`` CLI; no embedded sys.executable. + assert "cmind script update_graphs.py status" in cmd # PATH fallback for GUI-launched session starts (VS Code / IDE git UI). - assert "command -v rpgkit" in cmd - assert cmd.endswith("status 2>/dev/null || echo '[RPG-Kit] RPG status unavailable'") + assert "command -v cmind" in cmd + assert cmd.endswith("status 2>/dev/null || echo '[CoderMind] RPG status unavailable'") def test_install_claude_hooks_is_idempotent_across_python_upgrades(project, monkeypatch): """Re-installing must not stack duplicate SessionStart entries. Hooks no longer embed ``sys.executable``; they delegate to the - globally-installed ``rpgkit`` CLI. Re-running install therefore + globally-installed ``cmind`` CLI. Re-running install therefore yields the exact same command and must remain a single entry (not a duplicate per invocation). """ - rpgkit_cli._install_claude_hooks(project) + cmind_cli._install_claude_hooks(project) # Simulate any environment change that previously affected hook content; # the new hook body is interpreter-independent so this should be a no-op. - monkeypatch.setattr(rpgkit_cli.sys, "executable", "/opt/new-python/bin/python") - rpgkit_cli._install_claude_hooks(project) + monkeypatch.setattr(cmind_cli.sys, "executable", "/opt/new-python/bin/python") + cmind_cli._install_claude_hooks(project) data = json.loads((project / ".claude" / "settings.json").read_text()) session_start = data["hooks"]["SessionStart"] - rpgkit_entries = [ + cmind_entries = [ e for e in session_start if any("update_graphs.py" in h.get("command", "") for h in e.get("hooks", [])) ] - assert len(rpgkit_entries) == 1 - cmd = rpgkit_entries[0]["hooks"][0]["command"] - # Always uses the rpgkit-script form regardless of interpreter path. - assert "rpgkit script update_graphs.py" in cmd + assert len(cmind_entries) == 1 + cmd = cmind_entries[0]["hooks"][0]["command"] + # Always uses the cmind-script form regardless of interpreter path. + assert "cmind script update_graphs.py" in cmd assert "/opt/new-python/bin/python" not in cmd @@ -99,20 +99,20 @@ def test_install_claude_hooks_shell_escapes_special_chars(project, monkeypatch): Previously the hook embedded ``sys.executable`` and the workspace script path, requiring ``shlex.quote`` to survive spaces. The new - hook body invokes the global ``rpgkit`` CLI directly, so paths with + hook body invokes the global ``cmind`` CLI directly, so paths with special characters can't end up inside the command string. """ monkeypatch.setattr( - rpgkit_cli.sys, "executable", "/path with space/python" + cmind_cli.sys, "executable", "/path with space/python" ) - rpgkit_cli._install_claude_hooks(project) + cmind_cli._install_claude_hooks(project) cmd = ( json.loads((project / ".claude" / "settings.json").read_text()) ["hooks"]["SessionStart"][0]["hooks"][0]["command"] ) # No path leakage from the interpreter / workspace location. assert "/path with space" not in cmd - assert "rpgkit script update_graphs.py" in cmd + assert "cmind script update_graphs.py" in cmd def test_install_claude_hooks_merges_existing(project): @@ -127,7 +127,7 @@ def test_install_claude_hooks_merges_existing(project): "customField": "preserve me", })) - rpgkit_cli._install_claude_hooks(project) + cmind_cli._install_claude_hooks(project) data = json.loads((claude_dir / "settings.json").read_text()) # Existing event preserved assert data["hooks"]["PostToolUse"][0]["hooks"][0]["command"] == "echo user" @@ -144,16 +144,16 @@ def test_install_claude_hooks_merges_existing(project): # --------------------------------------------------------------------------- def test_install_copilot_hooks_writes_folder_open_task(project): - rpgkit_cli._install_copilot_hooks(project) + cmind_cli._install_copilot_hooks(project) tasks = json.loads((project / ".vscode" / "tasks.json").read_text()) assert tasks["version"] == "2.0.0" assert len(tasks["tasks"]) == 1 t = tasks["tasks"][0] - assert t["label"] == "RPG-Kit: load status" + assert t["label"] == "CoderMind: load status" assert t["runOptions"] == {"runOn": "folderOpen"} - # Task now invokes the global ``rpgkit`` CLI; args carry the + # Task now invokes the global ``cmind`` CLI; args carry the # dispatcher subcommand + script relpath, with ``status`` last. - assert t["command"] == "rpgkit" + assert t["command"] == "cmind" assert t["args"][0] == "script" assert t["args"][1] == "update_graphs.py" assert t["args"][-1] == "status" @@ -165,11 +165,11 @@ def test_install_copilot_hooks_writes_folder_open_task(project): def test_install_copilot_hooks_is_idempotent(project): - rpgkit_cli._install_copilot_hooks(project) - rpgkit_cli._install_copilot_hooks(project) + cmind_cli._install_copilot_hooks(project) + cmind_cli._install_copilot_hooks(project) tasks = json.loads((project / ".vscode" / "tasks.json").read_text()) labels = [t["label"] for t in tasks["tasks"]] - assert labels.count("RPG-Kit: load status") == 1 + assert labels.count("CoderMind: load status") == 1 def test_install_copilot_hooks_preserves_user_tasks(project): @@ -181,11 +181,11 @@ def test_install_copilot_hooks_preserves_user_tasks(project): {"label": "user build", "type": "shell", "command": "make"}, ], })) - rpgkit_cli._install_copilot_hooks(project) + cmind_cli._install_copilot_hooks(project) tasks = json.loads((vscode / "tasks.json").read_text()) labels = [t["label"] for t in tasks["tasks"]] assert "user build" in labels - assert "RPG-Kit: load status" in labels + assert "CoderMind: load status" in labels # --------------------------------------------------------------------------- @@ -196,14 +196,14 @@ def test_install_hooks_dispatches_to_copilot(project, monkeypatch): # Pretend the project is a git repo so the pre-commit installer fires. (project / ".git" / "hooks").mkdir(parents=True) - rpgkit_cli._install_hooks(project, "copilot", tracker=None) + cmind_cli._install_hooks(project, "copilot", tracker=None) # Copilot tasks.json present, Claude settings.json absent. assert (project / ".vscode" / "tasks.json").is_file() assert not (project / ".claude" / "settings.json").exists() # Pre-commit hook installed. pre = (project / ".git" / "hooks" / "pre-commit").read_text() - assert "RPG-Kit: incremental RPG sync on commit" in pre + assert "CoderMind: incremental RPG sync on commit" in pre assert "update_graphs.py" in pre and "sync" in pre # Hook must pass ``--staged-only`` so it doesn't pull working-tree # changes that the user hasn't ``git add``'d. @@ -213,7 +213,7 @@ def test_install_hooks_dispatches_to_copilot(project, monkeypatch): def test_install_hooks_dispatches_to_claude(project): (project / ".git" / "hooks").mkdir(parents=True) - rpgkit_cli._install_hooks(project, "claude", tracker=None) + cmind_cli._install_hooks(project, "claude", tracker=None) assert (project / ".claude" / "settings.json").is_file() assert not (project / ".vscode" / "tasks.json").exists() @@ -221,13 +221,13 @@ def test_install_hooks_dispatches_to_claude(project): def test_update_command_invokes_install_hooks(): - """Regression tripwire: ``rpgkit update`` must call ``_install_hooks``. + """Regression tripwire: ``cmind update`` must call ``_install_hooks``. Previously ``update`` re-downloaded templates / refreshed gitignore / regenerated MCP config but silently *skipped* hook installation. - Result: users running ``rpgkit update`` after upgrading the CLI + Result: users running ``cmind update`` after upgrading the CLI never received hook fixes \u2014 ``.git/hooks/*`` stayed frozen at - whatever version was active during the original ``rpgkit init``. + whatever version was active during the original ``cmind init``. This is a static-source assertion rather than an end-to-end test because ``update`` does network I/O (template download) that is @@ -236,15 +236,15 @@ def test_update_command_invokes_install_hooks(): call from ``update``, this test fails loudly. """ import inspect - source = inspect.getsource(rpgkit_cli.update) + source = inspect.getsource(cmind_cli.update) assert "_install_hooks(" in source, ( - "rpgkit update must call _install_hooks(...); " + "cmind update must call _install_hooks(...); " "without it, hook upgrades never propagate to existing workspaces" ) # And the tracker must declare a 'hooks' step so the user sees it # in the live progress output. assert '"hooks"' in source, ( - "rpgkit update tracker must declare a 'hooks' step" + "cmind update tracker must declare a 'hooks' step" ) @@ -258,7 +258,7 @@ def test_update_command_invokes_install_hooks(): # every upgrade was a silent no-op: users kept whatever they were first # installed with, and never picked up new behavior. The tests below # pin the upgrade semantics: a fresh install must REPLACE any prior -# RPG-Kit-owned content rather than refusing to write or stacking copies. +# CoderMind-owned content rather than refusing to write or stacking copies. def _hooks_dir(project): @@ -272,20 +272,20 @@ def test_pre_commit_v1_legacy_is_replaced_on_upgrade(project): hd = _hooks_dir(project) (hd / "pre-commit").write_text( "#!/bin/sh\n" - "# RPG-Kit: full RPG sync on commit\n" + "# CoderMind: full RPG sync on commit\n" "/old/python /old/update_graphs.py sync 2>/dev/null || true\n" ) - assert rpgkit_cli._install_git_pre_commit_hook(project) is True + assert cmind_cli._install_git_pre_commit_hook(project) is True text = (hd / "pre-commit").read_text() # Old marker + old command line are gone. - assert "# RPG-Kit: full RPG sync on commit" not in text + assert "# CoderMind: full RPG sync on commit" not in text assert "/old/python" not in text # New sentinel-wrapped block is present exactly once. - assert text.count("# RPGKIT-BEGIN pre-commit") == 1 - assert text.count("# RPGKIT-END pre-commit") == 1 - assert "# RPG-Kit: incremental RPG sync on commit" in text + assert text.count("# CMIND-BEGIN pre-commit") == 1 + assert text.count("# CMIND-END pre-commit") == 1 + assert "# CoderMind: incremental RPG sync on commit" in text assert "--staged-only" in text @@ -294,16 +294,16 @@ def test_post_commit_v1_legacy_is_replaced_on_upgrade(project): hd = _hooks_dir(project) (hd / "post-commit").write_text( "#!/bin/sh\n" - "# RPG-Kit: advance meta.git after commit\n" + "# CoderMind: advance meta.git after commit\n" "/old/python /old/update_graphs.py sync 2>/dev/null || true\n" ) - assert rpgkit_cli._install_git_post_commit_hook(project) is True + assert cmind_cli._install_git_post_commit_hook(project) is True text = (hd / "post-commit").read_text() - assert "# RPG-Kit: advance meta.git after commit" not in text + assert "# CoderMind: advance meta.git after commit" not in text assert "/old/python" not in text - assert text.count("# RPGKIT-BEGIN post-commit") == 1 + assert text.count("# CMIND-BEGIN post-commit") == 1 assert "update-rpg" in text # phase 2 is now present @@ -317,7 +317,7 @@ def test_post_commit_v3_legacy_is_replaced_on_upgrade(project): hd = _hooks_dir(project) old_body = ( "#!/bin/sh\n" - "# RPG-Kit: advance meta.git + background feature graph update\n" + "# CoderMind: advance meta.git + background feature graph update\n" "/old/python /old/update_graphs.py sync 2>/dev/null || true\n" "if [ ! -f /old/.lock ]; then\n" ' setsid env -u GIT_INDEX_FILE -u GIT_DIR sh -c "cd /old; sleep 2; touch /old/.lock; ' @@ -327,33 +327,33 @@ def test_post_commit_v3_legacy_is_replaced_on_upgrade(project): ) (hd / "post-commit").write_text(old_body) - assert rpgkit_cli._install_git_post_commit_hook(project) is True + assert cmind_cli._install_git_post_commit_hook(project) is True text = (hd / "post-commit").read_text() # Old paths are gone — proves the v3 block was actually stripped. assert "/old/python" not in text assert "/old/.lock" not in text # New sentinel block is present exactly once (no duplicate piling). - assert text.count("# RPGKIT-BEGIN post-commit") == 1 - assert text.count("# RPGKIT-END post-commit") == 1 + assert text.count("# CMIND-BEGIN post-commit") == 1 + assert text.count("# CMIND-END post-commit") == 1 # Current marker survives inside the new block. assert text.count( - "# RPG-Kit: advance meta.git + background feature graph update" + "# CoderMind: advance meta.git + background feature graph update" ) == 1 def test_install_is_idempotent_under_sentinels(project): """Repeated installs must not stack sentinel blocks or duplicate content — the second install replaces the first verbatim.""" hd = _hooks_dir(project) - rpgkit_cli._install_git_pre_commit_hook(project) + cmind_cli._install_git_pre_commit_hook(project) first = (hd / "pre-commit").read_text() - rpgkit_cli._install_git_pre_commit_hook(project) - rpgkit_cli._install_git_pre_commit_hook(project) + cmind_cli._install_git_pre_commit_hook(project) + cmind_cli._install_git_pre_commit_hook(project) third = (hd / "pre-commit").read_text() assert first == third - assert third.count("# RPGKIT-BEGIN pre-commit") == 1 - assert third.count("# RPGKIT-END pre-commit") == 1 + assert third.count("# CMIND-BEGIN pre-commit") == 1 + assert third.count("# CMIND-END pre-commit") == 1 def test_sentinel_block_is_atomically_replaceable(project): @@ -362,44 +362,44 @@ def test_sentinel_block_is_atomically_replaceable(project): (hd / "pre-commit").write_text( "#!/bin/sh\n" "\n" - "# RPGKIT-BEGIN pre-commit\n" - "# RPG-Kit: incremental RPG sync on commit\n" + "# CMIND-BEGIN pre-commit\n" + "# CoderMind: incremental RPG sync on commit\n" "/some/older/path/python /some/older/script.py sync --legacy-flag\n" - "# RPGKIT-END pre-commit\n" + "# CMIND-END pre-commit\n" ) - assert rpgkit_cli._install_git_pre_commit_hook(project) is True + assert cmind_cli._install_git_pre_commit_hook(project) is True text = (hd / "pre-commit").read_text() # Old body content gone. assert "/some/older/path/python" not in text assert "--legacy-flag" not in text # Exactly one sentinel pair. - assert text.count("# RPGKIT-BEGIN pre-commit") == 1 - assert text.count("# RPGKIT-END pre-commit") == 1 + assert text.count("# CMIND-BEGIN pre-commit") == 1 + assert text.count("# CMIND-END pre-commit") == 1 # New body present. assert "--staged-only" in text def test_user_authored_content_outside_block_is_preserved(project): - """RPG-Kit owns only its sentinel block; user-authored shell lines before/after the block must survive an install/upgrade.""" + """CoderMind owns only its sentinel block; user-authored shell lines before/after the block must survive an install/upgrade.""" hd = _hooks_dir(project) (hd / "pre-commit").write_text( "#!/bin/sh\n" "echo 'user-prelude: about to commit' >&2\n" - "# RPGKIT-BEGIN pre-commit\n" - "# RPG-Kit: incremental RPG sync on commit\n" + "# CMIND-BEGIN pre-commit\n" + "# CoderMind: incremental RPG sync on commit\n" "/old/python /old/update_graphs.py sync --staged-only\n" - "# RPGKIT-END pre-commit\n" + "# CMIND-END pre-commit\n" "echo 'user-postlude: still going' >&2\n" ) - assert rpgkit_cli._install_git_pre_commit_hook(project) is True + assert cmind_cli._install_git_pre_commit_hook(project) is True text = (hd / "pre-commit").read_text() assert "user-prelude" in text assert "user-postlude" in text - # And the RPG-Kit content was actually upgraded (old python path gone). + # And the CoderMind content was actually upgraded (old python path gone). assert "/old/python" not in text @@ -410,11 +410,11 @@ def test_user_authored_content_outside_block_is_preserved(project): def _run_status(workspace: Path, json_mode: bool = False) -> subprocess.CompletedProcess: """Run the real source ``update_graphs.py status`` with explicit ``--rpg`` and ``--dep-graph`` paths pointing into ``workspace``. - We invoke the source script (not the copy in ``workspace/.rpgkit/ + We invoke the source script (not the copy in ``workspace/.cmind/ scripts``) so the test doesn't need to vendor the ``common/`` and ``rpg/`` packages alongside it. """ - data_dir = workspace / ".rpgkit" / "data" + data_dir = workspace / ".cmind" / "data" cmd = [ sys.executable, str(_project_root / "scripts" / "update_graphs.py"), @@ -430,13 +430,13 @@ def _run_status(workspace: Path, json_mode: bool = False) -> subprocess.Complete def test_update_graphs_status_empty_workspace(project): result = _run_status(project) assert result.returncode == 0, result.stderr - # No RPG yet → guidance points the agent to /rpgkit.encode. + # No RPG yet → guidance points the agent to /cmind.encode. assert "No RPG found" in result.stdout - assert "/rpgkit.encode" in result.stdout + assert "/cmind.encode" in result.stdout def test_update_graphs_status_with_rpg(project): - data_dir = project / ".rpgkit" / "data" + data_dir = project / ".cmind" / "data" data_dir.mkdir(parents=True) (data_dir / "rpg.json").write_text(json.dumps({ "repo_name": "demo", @@ -473,7 +473,7 @@ def test_update_graphs_status_with_rpg(project): def test_update_graphs_status_handles_corrupt_files(project): - data_dir = project / ".rpgkit" / "data" + data_dir = project / ".cmind" / "data" data_dir.mkdir(parents=True) (data_dir / "rpg.json").write_text("{ this is not json") (data_dir / "dep_graph.json").write_text("also broken") @@ -489,14 +489,14 @@ def test_update_graphs_status_handles_corrupt_files(project): def test_update_graphs_status_text_on_corrupt_rpg_says_unavailable(project): """A corrupt rpg.json must NOT produce 'Repository Program Graph is available' text — that would mislead the AI agent into calling rpg-tools MCP queries that would all fail.""" - data_dir = project / ".rpgkit" / "data" + data_dir = project / ".cmind" / "data" data_dir.mkdir(parents=True) (data_dir / "rpg.json").write_text("not json at all") text = _run_status(project).stdout assert "is available" not in text assert "could not be parsed" in text - assert "/rpgkit.encode" in text + assert "/cmind.encode" in text # --------------------------------------------------------------------------- @@ -504,8 +504,8 @@ def test_update_graphs_status_text_on_corrupt_rpg_says_unavailable(project): # --------------------------------------------------------------------------- def test_setup_gitignore_greenfield_writes_full_template(tmp_path): - """No .git/, no .gitignore → Python standard template + all RPG-Kit rules.""" - rpgkit_cli._setup_gitignore(tmp_path, "copilot") + """No .git/, no .gitignore → Python standard template + all CoderMind rules.""" + cmind_cli._setup_gitignore(tmp_path, "copilot") content = (tmp_path / ".gitignore").read_text() # Python conventions (matches github/gitignore/Python.gitignore verbatim) assert "__pycache__/" in content @@ -515,8 +515,8 @@ def test_setup_gitignore_greenfield_writes_full_template(tmp_path): assert "PyInstaller" in content assert "Jupyter Notebook" in content assert ".ipynb_checkpoints" in content - # RPG-Kit common (runtime + machine-specific) - assert ".rpgkit/" in content + # CoderMind common (runtime + machine-specific) + assert ".cmind/" in content assert ".vscode/mcp.json" in content assert ".vscode/tasks.json" in content assert ".mcp.json" in content @@ -529,7 +529,7 @@ def test_setup_gitignore_greenfield_writes_full_template(tmp_path): def test_setup_gitignore_greenfield_claude(tmp_path): """Claude path uses .claude/commands/ instead of .github/*.""" - rpgkit_cli._setup_gitignore(tmp_path, "claude") + cmind_cli._setup_gitignore(tmp_path, "claude") content = (tmp_path / ".gitignore").read_text() assert ".claude/commands/" in content # Copilot directories must NOT be ignored on a Claude project @@ -537,13 +537,13 @@ def test_setup_gitignore_greenfield_claude(tmp_path): assert ".github/prompts/" not in content -def test_setup_gitignore_existing_git_no_ignore_writes_rpgkit_only(tmp_path): - """Existing .git/, no .gitignore → RPG-Kit rules only, NO Python template.""" +def test_setup_gitignore_existing_git_no_ignore_writes_cmind_only(tmp_path): + """Existing .git/, no .gitignore → CoderMind rules only, NO Python template.""" (tmp_path / ".git").mkdir() - rpgkit_cli._setup_gitignore(tmp_path, "copilot") + cmind_cli._setup_gitignore(tmp_path, "copilot") content = (tmp_path / ".gitignore").read_text() - # RPG-Kit rules present - assert ".rpgkit/" in content + # CoderMind rules present + assert ".cmind/" in content assert ".github/agents/" in content # Python conventions NOT imposed on existing repo assert "__pycache__/" not in content @@ -555,46 +555,46 @@ def test_setup_gitignore_existing_gitignore_preserves_user_entries(tmp_path): """Pre-existing .gitignore content must be preserved verbatim.""" user_content = "# My custom rules\nnode_modules/\n*.tmp\n" (tmp_path / ".gitignore").write_text(user_content) - rpgkit_cli._setup_gitignore(tmp_path, "copilot") + cmind_cli._setup_gitignore(tmp_path, "copilot") content = (tmp_path / ".gitignore").read_text() # User's entries preserved at the top, untouched assert content.startswith(user_content) assert "node_modules/" in content assert "*.tmp" in content - # RPG-Kit rules appended - assert ".rpgkit/" in content + # CoderMind rules appended + assert ".cmind/" in content assert ".github/agents/" in content def test_setup_gitignore_is_idempotent(tmp_path): """Running _setup_gitignore twice must not duplicate entries or headers.""" - rpgkit_cli._setup_gitignore(tmp_path, "copilot") + cmind_cli._setup_gitignore(tmp_path, "copilot") first = (tmp_path / ".gitignore").read_text() - rpgkit_cli._setup_gitignore(tmp_path, "copilot") + cmind_cli._setup_gitignore(tmp_path, "copilot") second = (tmp_path / ".gitignore").read_text() assert first == second # second call is a no-op - # No duplicate RPG-Kit header - assert second.count(rpgkit_cli._GITIGNORE_RPGKIT_HEADER) == 1 - # No duplicate .rpgkit/ directory entry. Count actual lines (after + # No duplicate CoderMind header + assert second.count(cmind_cli._GITIGNORE_CMIND_HEADER) == 1 + # No duplicate .cmind/ directory entry. Count actual lines (after # stripping) because the appended block also contains - # `!.rpgkit/config.toml` which holds .rpgkit/ as a substring. + # `!.cmind/config.toml` which holds .cmind/ as a substring. lines = [l.strip() for l in second.splitlines()] - assert lines.count(".rpgkit/") == 1 + assert lines.count(".cmind/") == 1 def test_setup_gitignore_partial_existing_rules_only_appends_missing(tmp_path): - """If user already has SOME RPG-Kit rules, only missing ones get appended.""" - # User has manually added .rpgkit/ but nothing else - (tmp_path / ".gitignore").write_text(".rpgkit/\n") - rpgkit_cli._setup_gitignore(tmp_path, "copilot") + """If user already has SOME CoderMind rules, only missing ones get appended.""" + # User has manually added .cmind/ but nothing else + (tmp_path / ".gitignore").write_text(".cmind/\n") + cmind_cli._setup_gitignore(tmp_path, "copilot") content = (tmp_path / ".gitignore").read_text() - # .rpgkit/ directory entry must NOT be duplicated. Compare exact + # .cmind/ directory entry must NOT be duplicated. Compare exact # lines (after stripping) because the appended block also contains - # `!.rpgkit/config.toml` which holds .rpgkit/ as a substring. + # `!.cmind/config.toml` which holds .cmind/ as a substring. lines = [l.strip() for l in content.splitlines()] - assert lines.count(".rpgkit/") == 1 + assert lines.count(".cmind/") == 1 # The new managed config.toml un-ignore line is present - assert "!.rpgkit/config.toml" in lines + assert "!.cmind/config.toml" in lines # Missing rules are now present assert ".vscode/mcp.json" in content assert ".github/agents/" in content @@ -605,8 +605,8 @@ def test_setup_gitignore_partial_existing_rules_only_appends_missing(tmp_path): # --------------------------------------------------------------------------- def test_install_claude_hooks_adds_mcp_rpg_tools_permission(project): - """Rpgkit init should pre-authorize mcp__rpg-tools so Claude Code does not prompt for every search_rpg / explore_rpg / get_node_detail / list_rpg_tree call.""" - rpgkit_cli._install_claude_hooks(project) + """Cmind init should pre-authorize mcp__rpg-tools so Claude Code does not prompt for every search_rpg / explore_rpg / get_node_detail / list_rpg_tree call.""" + cmind_cli._install_claude_hooks(project) data = json.loads((project / ".claude" / "settings.json").read_text()) assert "mcp__rpg-tools" in data["permissions"]["allow"] @@ -622,7 +622,7 @@ def test_install_claude_hooks_preserves_existing_permissions(project): } })) - rpgkit_cli._install_claude_hooks(project) + cmind_cli._install_claude_hooks(project) data = json.loads((claude_dir / "settings.json").read_text()) allow = data["permissions"]["allow"] # User entries preserved @@ -635,7 +635,7 @@ def test_install_claude_hooks_preserves_existing_permissions(project): assert "mcp__rpg-tools" in allow # Idempotent: second call must not re-append - rpgkit_cli._install_claude_hooks(project) + cmind_cli._install_claude_hooks(project) data2 = json.loads((claude_dir / "settings.json").read_text()) assert data2["permissions"]["allow"].count("mcp__rpg-tools") == 1 @@ -643,7 +643,7 @@ def test_install_claude_hooks_preserves_existing_permissions(project): def test_generate_mcp_config_copilot_omits_sandbox(tmp_path): """Copilot ``.vscode/mcp.json`` must NOT include sandbox keys. - Earlier versions of RPG-Kit enabled the VS Code MCP sandbox to + Earlier versions of CoderMind enabled the VS Code MCP sandbox to auto-approve tool confirmations, but the sandbox needs ``bwrap`` and ``socat`` on PATH — missing on WSL, minimal Docker, and stock macOS — and missing deps cause the server to crash with a useless @@ -651,11 +651,11 @@ def test_generate_mcp_config_copilot_omits_sandbox(tmp_path): and rely on VS Code's 'Always allow this server' setting for the UX win. """ - scripts_dir = tmp_path / ".rpgkit" / "scripts" + scripts_dir = tmp_path / ".cmind" / "scripts" scripts_dir.mkdir(parents=True) (scripts_dir / "mcp_server.py").write_text("# placeholder\n") - rpgkit_cli._generate_mcp_config(tmp_path, "copilot") + cmind_cli._generate_mcp_config(tmp_path, "copilot") cfg = json.loads((tmp_path / ".vscode" / "mcp.json").read_text()) server = cfg["servers"]["rpg-tools"] assert "sandboxEnabled" not in server @@ -667,11 +667,11 @@ def test_generate_mcp_config_copilot_omits_sandbox(tmp_path): def test_generate_mcp_config_claude_has_no_sandbox_field(tmp_path): """Claude uses .claude/settings.json permissions, not mcp.json sandbox. The .mcp.json file should stay clean of Copilot-specific keys to avoid confusion.""" - scripts_dir = tmp_path / ".rpgkit" / "scripts" + scripts_dir = tmp_path / ".cmind" / "scripts" scripts_dir.mkdir(parents=True) (scripts_dir / "mcp_server.py").write_text("# placeholder\n") - rpgkit_cli._generate_mcp_config(tmp_path, "claude") + cmind_cli._generate_mcp_config(tmp_path, "claude") cfg = json.loads((tmp_path / ".mcp.json").read_text()) server = cfg["mcpServers"]["rpg-tools"] assert "sandboxEnabled" not in server diff --git a/CoderMind/tests/test_initial_encode_prompt.py b/CoderMind/tests/test_initial_encode_prompt.py index ecbad37..9bee89f 100644 --- a/CoderMind/tests/test_initial_encode_prompt.py +++ b/CoderMind/tests/test_initial_encode_prompt.py @@ -1,8 +1,8 @@ #!/usr/bin/env python3 -"""Tests for the optional initial-encode prompt at the end of ``rpgkit init``. +"""Tests for the optional initial-encode prompt at the end of ``cmind init``. Covers: - * ``_workspace_has_python_code`` correctly ignores ``.rpgkit/`` (the + * ``_workspace_has_python_code`` correctly ignores ``.cmind/`` (the runtime-script tree we just extracted) and other boilerplate dirs. * ``_maybe_offer_initial_encode`` skips silently when: - rpg.json already exists, @@ -24,7 +24,7 @@ _project_root = Path(__file__).resolve().parent.parent sys.path.insert(0, str(_project_root / "src")) -import rpgkit_cli # noqa: E402 +import cmind_cli # noqa: E402 # --------------------------------------------------------------------------- @@ -33,27 +33,27 @@ def test_workspace_has_python_code_finds_user_file(tmp_path): (tmp_path / "main.py").write_text("print('hi')\n") - assert rpgkit_cli._workspace_has_python_code(tmp_path) is True + assert cmind_cli._workspace_has_python_code(tmp_path) is True def test_workspace_has_python_code_finds_nested_file(tmp_path): sub = tmp_path / "src" / "pkg" sub.mkdir(parents=True) (sub / "mod.py").write_text("\n") - assert rpgkit_cli._workspace_has_python_code(tmp_path) is True + assert cmind_cli._workspace_has_python_code(tmp_path) is True -def test_workspace_has_python_code_ignores_rpgkit_runtime(tmp_path): - """Every workspace gets ``.rpgkit/scripts/*.py`` after init. +def test_workspace_has_python_code_ignores_cmind_runtime(tmp_path): + """Every workspace gets ``.cmind/scripts/*.py`` after init. Without the prune, this would always return True and make the prompt fire even for empty workspaces. """ - rpgkit_scripts = tmp_path / ".rpgkit" / "scripts" - rpgkit_scripts.mkdir(parents=True) - (rpgkit_scripts / "mcp_server.py").write_text("\n") - (rpgkit_scripts / "update_graphs.py").write_text("\n") - assert rpgkit_cli._workspace_has_python_code(tmp_path) is False + cmind_scripts = tmp_path / ".cmind" / "scripts" + cmind_scripts.mkdir(parents=True) + (cmind_scripts / "mcp_server.py").write_text("\n") + (cmind_scripts / "update_graphs.py").write_text("\n") + assert cmind_cli._workspace_has_python_code(tmp_path) is False def test_workspace_has_python_code_ignores_common_junk_dirs(tmp_path): @@ -61,11 +61,11 @@ def test_workspace_has_python_code_ignores_common_junk_dirs(tmp_path): sub = tmp_path / junk sub.mkdir() (sub / "noise.py").write_text("\n") - assert rpgkit_cli._workspace_has_python_code(tmp_path) is False + assert cmind_cli._workspace_has_python_code(tmp_path) is False def test_workspace_has_python_code_empty(tmp_path): - assert rpgkit_cli._workspace_has_python_code(tmp_path) is False + assert cmind_cli._workspace_has_python_code(tmp_path) is False # --------------------------------------------------------------------------- @@ -75,15 +75,15 @@ def test_workspace_has_python_code_empty(tmp_path): def test_skip_when_rpg_already_exists(tmp_path): """If rpg.json is already present, never prompt nor run.""" (tmp_path / "main.py").write_text("\n") - rpg_file = tmp_path / ".rpgkit" / "data" / "rpg.json" + rpg_file = tmp_path / ".cmind" / "data" / "rpg.json" rpg_file.parent.mkdir(parents=True) rpg_file.write_text("{}") - with patch.object(rpgkit_cli, "_run_initial_encode") as run, \ + with patch.object(cmind_cli, "_run_initial_encode") as run, \ patch("typer.confirm") as confirm: - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=True) - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=False) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=True) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=False) assert run.call_count == 0 assert confirm.call_count == 0 @@ -93,9 +93,9 @@ def test_skip_when_no_encode_flag(tmp_path): """``--no-encode`` must skip even when there's Python code.""" (tmp_path / "main.py").write_text("\n") - with patch.object(rpgkit_cli, "_run_initial_encode") as run, \ + with patch.object(cmind_cli, "_run_initial_encode") as run, \ patch("typer.confirm") as confirm: - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=False) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=False) run.assert_not_called() confirm.assert_not_called() @@ -104,9 +104,9 @@ def test_skip_when_no_encode_flag(tmp_path): def test_skip_when_no_python_code_and_interactive(tmp_path): """Empty workspace + interactive → no prompt, no run.""" with patch("sys.stdin.isatty", return_value=True), \ - patch.object(rpgkit_cli, "_run_initial_encode") as run, \ + patch.object(cmind_cli, "_run_initial_encode") as run, \ patch("typer.confirm") as confirm: - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) run.assert_not_called() confirm.assert_not_called() @@ -116,9 +116,9 @@ def test_skip_when_not_a_tty(tmp_path): """Non-tty (CI / piped) skips the prompt entirely.""" (tmp_path / "main.py").write_text("\n") with patch("sys.stdin.isatty", return_value=False), \ - patch.object(rpgkit_cli, "_run_initial_encode") as run, \ + patch.object(cmind_cli, "_run_initial_encode") as run, \ patch("typer.confirm") as confirm: - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) run.assert_not_called() confirm.assert_not_called() @@ -130,9 +130,9 @@ def test_skip_when_not_a_tty(tmp_path): def test_explicit_encode_flag_runs_without_prompt(tmp_path): """``--encode`` bypasses the prompt even for an empty workspace.""" - with patch.object(rpgkit_cli, "_run_initial_encode") as run, \ + with patch.object(cmind_cli, "_run_initial_encode") as run, \ patch("typer.confirm") as confirm: - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=True) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=True) run.assert_called_once_with(tmp_path) confirm.assert_not_called() @@ -141,9 +141,9 @@ def test_explicit_encode_flag_runs_without_prompt(tmp_path): def test_interactive_yes_runs_encoder(tmp_path): (tmp_path / "main.py").write_text("\n") with patch("sys.stdin.isatty", return_value=True), \ - patch.object(rpgkit_cli, "_run_initial_encode") as run, \ + patch.object(cmind_cli, "_run_initial_encode") as run, \ patch("typer.confirm", return_value=True) as confirm: - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) confirm.assert_called_once() run.assert_called_once_with(tmp_path) @@ -152,9 +152,9 @@ def test_interactive_yes_runs_encoder(tmp_path): def test_interactive_no_skips_encoder(tmp_path): (tmp_path / "main.py").write_text("\n") with patch("sys.stdin.isatty", return_value=True), \ - patch.object(rpgkit_cli, "_run_initial_encode") as run, \ + patch.object(cmind_cli, "_run_initial_encode") as run, \ patch("typer.confirm", return_value=False) as confirm: - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) confirm.assert_called_once() run.assert_not_called() @@ -164,9 +164,9 @@ def test_keyboard_interrupt_during_prompt_does_not_propagate(tmp_path): """Ctrl-C at the y/N prompt must not crash init.""" (tmp_path / "main.py").write_text("\n") with patch("sys.stdin.isatty", return_value=True), \ - patch.object(rpgkit_cli, "_run_initial_encode") as run, \ + patch.object(cmind_cli, "_run_initial_encode") as run, \ patch("typer.confirm", side_effect=KeyboardInterrupt): - rpgkit_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) + cmind_cli._maybe_offer_initial_encode(tmp_path, encode_choice=None) run.assert_not_called() @@ -176,9 +176,9 @@ def test_keyboard_interrupt_during_prompt_does_not_propagate(tmp_path): # --------------------------------------------------------------------------- def test_run_initial_encode_missing_script_returns_false(tmp_path): - """If .rpgkit/scripts/rpg_encoder/run_encode.py is absent, we warn + """If .cmind/scripts/rpg_encoder/run_encode.py is absent, we warn and return False without raising.""" - assert rpgkit_cli._run_initial_encode(tmp_path) is False + assert cmind_cli._run_initial_encode(tmp_path) is False # --------------------------------------------------------------------------- @@ -199,19 +199,19 @@ def _fresh_state(): def test_parse_line_generating_repo_info(): s = _fresh_state() - rpgkit_cli._parse_encoder_line("RPGParser - INFO - Generating repo info (max_iters=3)", s) + cmind_cli._parse_encoder_line("RPGParser - INFO - Generating repo info (max_iters=3)", s) assert "Generating repository overview" in s["phase"] def test_parse_line_repo_info_iter(): s = _fresh_state() - rpgkit_cli._parse_encoder_line("RPGParser - INFO - LLM call for repo info, iter=2...", s) + cmind_cli._parse_encoder_line("RPGParser - INFO - LLM call for repo info, iter=2...", s) assert "iter 2" in s["phase"] def test_parse_line_exclude_vote(): s = _fresh_state() - rpgkit_cli._parse_encoder_line("RPGParser - INFO - LLM vote #3 for exclude list...", s) + cmind_cli._parse_encoder_line("RPGParser - INFO - LLM vote #3 for exclude list...", s) assert "vote #3" in s["phase"] @@ -219,38 +219,38 @@ def test_parse_line_excluding_irrelevant_files(): """Matches the encoder's actual ``Excluding irrelevant files (max_votes=...)`` log line — not a fabricated marker.""" s = _fresh_state() - rpgkit_cli._parse_encoder_line( + cmind_cli._parse_encoder_line( "RPGParser - INFO - Excluding irrelevant files (max_votes=1)...", s) assert s["phase"] == "Selecting files to exclude" def test_parse_line_total_files(): s = _fresh_state() - rpgkit_cli._parse_encoder_line("RPGParser - INFO - Total valid Python files to parse: 42", s) + cmind_cli._parse_encoder_line("RPGParser - INFO - Total valid Python files to parse: 42", s) assert s["total_files"] == 42 assert "42 files" in s["phase"] def test_parse_line_class_batches_and_progress(): s = _fresh_state() - rpgkit_cli._parse_encoder_line( + cmind_cli._parse_encoder_line( "RPGParser - INFO - [GLOBAL] kind=class, groups=5, batches=7, foo=bar", s) assert s["kind"] == "class" assert s["class_total"] == 7 - rpgkit_cli._parse_encoder_line( + cmind_cli._parse_encoder_line( "RPGParser - INFO - [GLOBAL] process_class_batch: classes=['A'], units=3", s) - rpgkit_cli._parse_encoder_line( + cmind_cli._parse_encoder_line( "RPGParser - INFO - [GLOBAL] process_class_batch: classes=['B'], units=2", s) assert s["class_done"] == 2 def test_parse_line_function_batches_and_progress(): s = _fresh_state() - rpgkit_cli._parse_encoder_line( + cmind_cli._parse_encoder_line( "RPGParser - INFO - [GLOBAL] kind=function, groups=4, batches=6, foo=bar", s) assert s["kind"] == "function" assert s["func_total"] == 6 - rpgkit_cli._parse_encoder_line( + cmind_cli._parse_encoder_line( "RPGParser - INFO - [GLOBAL] process_func_batch: functions=['f'], units=1", s) assert s["func_done"] == 1 @@ -258,7 +258,7 @@ def test_parse_line_function_batches_and_progress(): def test_parse_line_refactoring_clears_kind(): s = _fresh_state() s["kind"] = "function" - rpgkit_cli._parse_encoder_line("RPGParser - INFO - Refactoring to RPG...", s) + cmind_cli._parse_encoder_line("RPGParser - INFO - Refactoring to RPG...", s) assert s["kind"] is None assert "Refactoring" in s["phase"] @@ -266,7 +266,7 @@ def test_parse_line_refactoring_clears_kind(): def test_parse_line_unknown_is_ignored(): """Unrecognised lines must leave state untouched (best-effort parser).""" s = _fresh_state() - rpgkit_cli._parse_encoder_line("some completely unrelated line", s) + cmind_cli._parse_encoder_line("some completely unrelated line", s) assert s == _fresh_state() @@ -280,7 +280,7 @@ def _make_fake_encoder(tmp_path: Path, exit_code: int, stderr_lines: list, stdou Using a real subprocess (rather than mocking Popen) keeps the test honest: it exercises the actual threaded reader + Progress loop. """ - encoder_dir = tmp_path / ".rpgkit" / "scripts" / "rpg_encoder" + encoder_dir = tmp_path / ".cmind" / "scripts" / "rpg_encoder" encoder_dir.mkdir(parents=True) script = encoder_dir / "run_encode.py" payload = { @@ -320,8 +320,8 @@ def test_run_initial_encode_success_writes_log(tmp_path): ], stdout_text='{"status": "success"}\n', ) - assert rpgkit_cli._run_initial_encode(tmp_path) is True - log = tmp_path / ".rpgkit" / "logs" / "encode.log" + assert cmind_cli._run_initial_encode(tmp_path) is True + log = tmp_path / ".cmind" / "logs" / "encode.log" assert log.is_file() contents = log.read_text() assert "Generating repo info" in contents @@ -336,7 +336,7 @@ def test_run_initial_encode_failure_returns_false(tmp_path): stderr_lines=["RPGParser - ERROR - boom"], stdout_text='{"status": "failed", "error": "boom"}\n', ) - assert rpgkit_cli._run_initial_encode(tmp_path) is False - log = tmp_path / ".rpgkit" / "logs" / "encode.log" + assert cmind_cli._run_initial_encode(tmp_path) is False + log = tmp_path / ".cmind" / "logs" / "encode.log" assert log.is_file() assert "boom" in log.read_text() diff --git a/CoderMind/tests/test_integration.py b/CoderMind/tests/test_integration.py index 3740c29..cbf5d9d 100644 --- a/CoderMind/tests/test_integration.py +++ b/CoderMind/tests/test_integration.py @@ -807,13 +807,13 @@ def test_merged_rpg_evolution_compatible(self, rpg_with_structure): def test_save_and_load_workflow(self, rpg_with_structure): """Full save-load-verify cycle with WorkflowIntegration.""" with tempfile.TemporaryDirectory() as tmpdir: - rpgkit_dir = os.path.join(tmpdir, ".rpgkit") - os.makedirs(rpgkit_dir, exist_ok=True) + cmind_dir = os.path.join(tmpdir, ".cmind") + os.makedirs(cmind_dir, exist_ok=True) # Save save_result = WorkflowIntegration.save_rpg( rpg=rpg_with_structure, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, message="Integration test save", source="encoded", ) @@ -821,7 +821,7 @@ def test_save_and_load_workflow(self, rpg_with_structure): assert save_result["version"] == 1 # Load - loaded = WorkflowIntegration.load_rpg(rpgkit_dir) + loaded = WorkflowIntegration.load_rpg(cmind_dir) assert loaded is not None assert loaded.repo_name == "test_project" diff --git a/CoderMind/tests/test_rpg_git_meta.py b/CoderMind/tests/test_rpg_git_meta.py index aaa3d3b..8be783e 100644 --- a/CoderMind/tests/test_rpg_git_meta.py +++ b/CoderMind/tests/test_rpg_git_meta.py @@ -319,7 +319,7 @@ def test_status_legacy_rpg_without_meta_still_works(tmp_path, git_repo): data = _run_status_json(rpg_path, cwd=git_repo) assert "last_synced_commit" not in data - # current_commit is still surfaced — useful when /rpgkit.encode runs next + # current_commit is still surfaced — useful when /cmind.encode runs next assert "current_commit" in data # Text-mode output should not advertise sync state diff --git a/CoderMind/tests/test_rpg_io.py b/CoderMind/tests/test_rpg_io.py index 1d9784d..2322867 100644 --- a/CoderMind/tests/test_rpg_io.py +++ b/CoderMind/tests/test_rpg_io.py @@ -29,12 +29,12 @@ def _has_git() -> bool: def _make_home_layout(tmp_path: Path, hash_id: str = "abc123def456") -> Path: - """Create the ``~/.rpgkit/workspaces//`` layout for tests. + """Create the ``~/.cmind/workspaces//`` layout for tests. Returns the home_dir (the dir that gets ``git init``). Caller is responsible for git-initialising and snapshotting it. """ - home_root = tmp_path / ".rpgkit" / "workspaces" / hash_id + home_root = tmp_path / ".cmind" / "workspaces" / hash_id (home_root / "data").mkdir(parents=True) return home_root @@ -201,7 +201,7 @@ def test_returns_none_when_history_has_no_valid_snapshot( def test_works_when_target_outside_known_layout( self, tmp_path: Path ) -> None: - """For paths that don't look like ``~/.rpgkit/workspaces/...``, + """For paths that don't look like ``~/.cmind/workspaces/...``, recovery silently no-ops and the original error re-raises.""" target = tmp_path / "rpg.json" # not in a home-layout target.write_text("not valid") diff --git a/CoderMind/tests/test_rpg_models.py b/CoderMind/tests/test_rpg_models.py index cb94b84..dd98397 100644 --- a/CoderMind/tests/test_rpg_models.py +++ b/CoderMind/tests/test_rpg_models.py @@ -4,7 +4,7 @@ - EdgeType extension (COMPOSES, IMPORTS, is_hierarchy) - RPG new attributes (dep_graph, _dep_to_rpg_map) - RPG new query methods (get_node_by_id, get_nodes_by_type, etc.) -- RPG-Kit nested format serialization round-trip +- CoderMind nested format serialization round-trip - ZeroRepo flat format loading - Backward compatibility (existing to_dict/from_dict unchanged) """ @@ -333,7 +333,7 @@ def test_feature_only_false(self, sample_rpg): # ────────────────────────────────────────────────────────────── -# Serialization: RPG-Kit nested format round-trip +# Serialization: CoderMind nested format round-trip # ────────────────────────────────────────────────────────────── class TestNestedFormatRoundTrip: @@ -381,7 +381,7 @@ def test_file_round_trip(self, sample_rpg): def test_has_root_field(self, sample_rpg): d = sample_rpg.to_dict() assert "root" in d - assert "nodes" not in d # RPG-Kit format has root, not nodes + assert "nodes" not in d # CoderMind format has root, not nodes assert "_dep_to_rpg_map" in d diff --git a/CoderMind/tests/test_rpg_service_path_conv.py b/CoderMind/tests/test_rpg_service_path_conv.py index 6f48c4e..7df7247 100644 --- a/CoderMind/tests/test_rpg_service_path_conv.py +++ b/CoderMind/tests/test_rpg_service_path_conv.py @@ -1,10 +1,10 @@ -"""Regression tests for the ``rpgkit update`` path-format bugs. +"""Regression tests for the ``cmind update`` path-format bugs. After unifying RPG node paths to the canonical codegen format (``file::Name`` / ``file::Cls::method``) the ``RPGService`` helpers that bridge between dep_graph node IDs and RPG ``meta.path`` strings were producing legacy ``::class X`` forms, which would silently revert -canonical paths to legacy on every ``rpgkit update`` run. These tests +canonical paths to legacy on every ``cmind update`` run. These tests pin down the canonical behavior so the regression does not re-emerge. """ @@ -155,7 +155,7 @@ def test_method_roundtrip(self): class TestProcessDiffSignature: def test_max_exclude_votes_parameter_exists(self): - """``rpgkit update`` should not silently spend 4 LLM calls on exclude_files; ``process_diff`` must accept and propagate the ``max_exclude_votes`` parameter so callers can opt for the single-call default.""" + """``cmind update`` should not silently spend 4 LLM calls on exclude_files; ``process_diff`` must accept and propagate the ``max_exclude_votes`` parameter so callers can opt for the single-call default.""" import inspect from rpg_encoder.rpg_evolution import RPGEvolution sig = inspect.signature(RPGEvolution.process_diff) diff --git a/CoderMind/tests/test_step3_polish.py b/CoderMind/tests/test_step3_polish.py index 5d411c3..fd2af4a 100644 --- a/CoderMind/tests/test_step3_polish.py +++ b/CoderMind/tests/test_step3_polish.py @@ -32,7 +32,7 @@ sys.path.insert(0, str(_project_root / "src")) sys.path.insert(0, str(_project_root / "scripts")) -import rpgkit_cli # noqa: E402 +import cmind_cli # noqa: E402 from rpg.models import RPG # noqa: E402 from rpg.service import RPGService # noqa: E402 @@ -56,7 +56,7 @@ def test_resolve_git_hooks_dir_for_plain_repo(tmp_path): repo = tmp_path / "repo" repo.mkdir() _sh(repo, "init", "-q") - hooks = rpgkit_cli._resolve_git_hooks_dir(repo) + hooks = cmind_cli._resolve_git_hooks_dir(repo) assert hooks is not None assert hooks == repo / ".git" / "hooks" assert hooks.is_dir() @@ -79,14 +79,14 @@ def test_resolve_git_hooks_dir_for_worktree(tmp_path): # Sanity: ``.git`` inside the worktree is indeed a file, not a dir assert (wt / ".git").is_file() - hooks = rpgkit_cli._resolve_git_hooks_dir(wt) + hooks = cmind_cli._resolve_git_hooks_dir(wt) assert hooks is not None, "worktree must resolve to a hooks dir" # Worktrees share the main repo's hooks assert hooks == main / ".git" / "hooks" def test_resolve_git_hooks_dir_for_non_git_returns_none(tmp_path): - assert rpgkit_cli._resolve_git_hooks_dir(tmp_path) is None + assert cmind_cli._resolve_git_hooks_dir(tmp_path) is None def test_resolve_git_hooks_dir_honors_core_hooks_path_override(tmp_path): @@ -104,7 +104,7 @@ def test_resolve_git_hooks_dir_honors_core_hooks_path_override(tmp_path): custom_hooks.mkdir() _sh(repo, "config", "core.hooksPath", str(custom_hooks)) - resolved = rpgkit_cli._resolve_git_hooks_dir(repo) + resolved = cmind_cli._resolve_git_hooks_dir(repo) assert resolved is not None assert resolved == custom_hooks @@ -117,7 +117,7 @@ def test_resolve_git_hooks_dir_with_relative_core_hooks_path(tmp_path): (repo / ".husky").mkdir() _sh(repo, "config", "core.hooksPath", ".husky") - resolved = rpgkit_cli._resolve_git_hooks_dir(repo) + resolved = cmind_cli._resolve_git_hooks_dir(repo) assert resolved is not None assert resolved.resolve() == (repo / ".husky").resolve() @@ -130,7 +130,7 @@ def test_resolve_git_hooks_dir_empty_core_hooks_path_falls_back(tmp_path): # Explicitly set then unset to exercise the empty-value path. _sh(repo, "config", "core.hooksPath", "") - resolved = rpgkit_cli._resolve_git_hooks_dir(repo) + resolved = cmind_cli._resolve_git_hooks_dir(repo) assert resolved is not None assert resolved == repo / ".git" / "hooks" @@ -144,13 +144,13 @@ def test_install_pre_commit_hook_via_core_hooks_path(tmp_path): custom_hooks.mkdir() _sh(repo, "config", "core.hooksPath", str(custom_hooks)) - assert rpgkit_cli._install_git_pre_commit_hook(repo) is True + assert cmind_cli._install_git_pre_commit_hook(repo) is True # Hook landed in the custom dir, NOT in .git/hooks. assert (custom_hooks / "pre-commit").is_file() assert not (repo / ".git" / "hooks" / "pre-commit").exists() text = (custom_hooks / "pre-commit").read_text() - assert "RPGKIT-BEGIN pre-commit" in text + assert "CMIND-BEGIN pre-commit" in text assert "--staged-only" in text @@ -167,11 +167,11 @@ def test_install_pre_commit_hook_in_worktree(tmp_path): wt = tmp_path / "wt" _sh(main, "worktree", "add", "--detach", str(wt)) - assert rpgkit_cli._install_git_pre_commit_hook(wt) is True + assert cmind_cli._install_git_pre_commit_hook(wt) is True # Hook landed in the shared hooks dir (main repo) not the worktree pre_commit = main / ".git" / "hooks" / "pre-commit" assert pre_commit.is_file() - assert "RPG-Kit: incremental RPG sync on commit" in pre_commit.read_text() + assert "CoderMind: incremental RPG sync on commit" in pre_commit.read_text() # =========================================================================== @@ -192,7 +192,7 @@ def synced_repo_with_branch(tmp_path): _sh(repo, "commit", "-q", "-m", "c1") head = _sh(repo, "rev-parse", "HEAD") - data_dir = repo / ".rpgkit" / "data" + data_dir = repo / ".cmind" / "data" data_dir.mkdir(parents=True) rpg_path = data_dir / "rpg.json" dep_graph_path = data_dir / "dep_graph.json" @@ -253,7 +253,7 @@ def test_status_text_omits_branch_when_detached(tmp_path): head = _sh(repo, "rev-parse", "HEAD") _sh(repo, "-c", "advice.detachedHead=false", "checkout", "-q", head) - data_dir = repo / ".rpgkit" / "data" + data_dir = repo / ".cmind" / "data" data_dir.mkdir(parents=True) rpg_path = data_dir / "rpg.json" dep_graph_path = data_dir / "dep_graph.json" @@ -319,11 +319,11 @@ def test_noop_skips_refresh_when_nothing_changed(synced_repo_with_branch): def test_noop_respects_no_git_meta_env(synced_repo_with_branch, monkeypatch): - """``RPGKIT_NO_GIT_META=1`` must veto the branch refresh too.""" + """``CMIND_NO_GIT_META=1`` must veto the branch refresh too.""" repo, rpg_path, dep_graph_path, code, _ = synced_repo_with_branch _sh(repo, "branch", "-m", "develop") - monkeypatch.setenv("RPGKIT_NO_GIT_META", "1") + monkeypatch.setenv("CMIND_NO_GIT_META", "1") svc = RPGService.load(str(rpg_path)) result = svc.sync_from_commit_diff( code_dir=str(code), workspace_root=str(repo), @@ -344,11 +344,11 @@ def test_install_post_merge_hook_writes_script(tmp_path): repo.mkdir() _sh(repo, "init", "-q") - assert rpgkit_cli._install_git_post_merge_hook(repo) is True + assert cmind_cli._install_git_post_merge_hook(repo) is True post_merge = repo / ".git" / "hooks" / "post-merge" assert post_merge.is_file() content = post_merge.read_text() - assert "RPG-Kit: incremental RPG sync after merge / pull" in content + assert "CoderMind: incremental RPG sync after merge / pull" in content assert "update_graphs.py" in content and " sync " in content # post-merge fires AFTER files are in the working tree, no staging # area exists at that point — so the hook must NOT use --staged-only. @@ -362,12 +362,12 @@ def test_install_post_merge_hook_is_idempotent(tmp_path): repo = tmp_path / "repo" repo.mkdir() _sh(repo, "init", "-q") - rpgkit_cli._install_git_post_merge_hook(repo) - rpgkit_cli._install_git_post_merge_hook(repo) - rpgkit_cli._install_git_post_merge_hook(repo) + cmind_cli._install_git_post_merge_hook(repo) + cmind_cli._install_git_post_merge_hook(repo) + cmind_cli._install_git_post_merge_hook(repo) post_merge = (repo / ".git" / "hooks" / "post-merge").read_text() # Marker appears exactly once - assert post_merge.count("RPG-Kit: incremental RPG sync after merge / pull") == 1 + assert post_merge.count("CoderMind: incremental RPG sync after merge / pull") == 1 def test_install_post_merge_hook_preserves_existing_user_hook(tmp_path): @@ -380,22 +380,22 @@ def test_install_post_merge_hook_preserves_existing_user_hook(tmp_path): user_hook.write_text("#!/bin/sh\necho 'user custom hook'\n") user_hook.chmod(0o755) - rpgkit_cli._install_git_post_merge_hook(repo) + cmind_cli._install_git_post_merge_hook(repo) content = user_hook.read_text() assert "echo 'user custom hook'" in content - assert "RPG-Kit: incremental RPG sync after merge / pull" in content + assert "CoderMind: incremental RPG sync after merge / pull" in content def test_install_hooks_installs_both_pre_commit_and_post_merge(tmp_path): """End-to-end: ``_install_hooks`` should produce all three hooks.""" project = tmp_path / "proj" project.mkdir() - (project / ".rpgkit" / "scripts").mkdir(parents=True) + (project / ".cmind" / "scripts").mkdir(parents=True) # Stub script so installer reports OK (only the path string matters) - (project / ".rpgkit" / "scripts" / "update_graphs.py").write_text("") + (project / ".cmind" / "scripts" / "update_graphs.py").write_text("") _sh(project, "init", "-q") - rpgkit_cli._install_hooks(project, "copilot", tracker=None) + cmind_cli._install_hooks(project, "copilot", tracker=None) pre_commit = project / ".git" / "hooks" / "pre-commit" post_commit = project / ".git" / "hooks" / "post-commit" @@ -417,11 +417,11 @@ def test_install_post_commit_hook_writes_script(tmp_path): repo.mkdir() _sh(repo, "init", "-q") - assert rpgkit_cli._install_git_post_commit_hook(repo) is True + assert cmind_cli._install_git_post_commit_hook(repo) is True post_commit = repo / ".git" / "hooks" / "post-commit" assert post_commit.is_file() content = post_commit.read_text() - assert "RPG-Kit: advance meta.git + background feature graph update" in content + assert "CoderMind: advance meta.git + background feature graph update" in content assert "update_graphs.py" in content and " sync " in content assert "update-rpg" in content # Must unset GIT_INDEX_FILE to avoid hook env var leaking into @@ -448,22 +448,22 @@ def test_install_post_commit_hook_is_idempotent(tmp_path): repo = tmp_path / "repo" repo.mkdir() _sh(repo, "init", "-q") - rpgkit_cli._install_git_post_commit_hook(repo) - rpgkit_cli._install_git_post_commit_hook(repo) - rpgkit_cli._install_git_post_commit_hook(repo) + cmind_cli._install_git_post_commit_hook(repo) + cmind_cli._install_git_post_commit_hook(repo) + cmind_cli._install_git_post_commit_hook(repo) text = (repo / ".git" / "hooks" / "post-commit").read_text() - assert text.count("RPG-Kit: advance meta.git + background feature graph update") == 1 + assert text.count("CoderMind: advance meta.git + background feature graph update") == 1 def test_workspace_root_resolution_prefers_cwd_over_env(tmp_path, monkeypatch): - """Regression: hooks spawned by ``git`` always have cwd at the repo root. If a parent process previously set ``RPGKIT_WORKSPACE`` to a different workspace (e.g. the developer's RPG-Kit dev env), the inherited env var must NOT override the hook's actual workspace.""" + """Regression: hooks spawned by ``git`` always have cwd at the repo root. If a parent process previously set ``CMIND_WORKSPACE`` to a different workspace (e.g. the developer's CoderMind dev env), the inherited env var must NOT override the hook's actual workspace.""" # Set up two distinct workspaces real_ws = tmp_path / "real-ws" - (real_ws / ".rpgkit").mkdir(parents=True) + (real_ws / ".cmind").mkdir(parents=True) decoy_ws = tmp_path / "decoy-ws" - (decoy_ws / ".rpgkit").mkdir(parents=True) + (decoy_ws / ".cmind").mkdir(parents=True) - monkeypatch.setenv("RPGKIT_WORKSPACE", str(decoy_ws)) + monkeypatch.setenv("CMIND_WORKSPACE", str(decoy_ws)) monkeypatch.chdir(real_ws) # Importing common.paths now should resolve to real_ws (cwd wins) diff --git a/CoderMind/tests/test_step4_integration.py b/CoderMind/tests/test_step4_integration.py index e77216f..c58c465 100644 --- a/CoderMind/tests/test_step4_integration.py +++ b/CoderMind/tests/test_step4_integration.py @@ -63,7 +63,7 @@ def codegen_workspace(tmp_path, monkeypatch): (code / "a.py").write_text("def a(): return 1\n") (code / "b.py").write_text("from a import a\ndef b(): return a() + 1\n") - data_dir = ws / ".rpgkit" / "data" + data_dir = ws / ".cmind" / "data" data_dir.mkdir(parents=True) rpg_path = data_dir / "rpg.json" dep_graph_path = data_dir / "dep_graph.json" @@ -311,7 +311,7 @@ def update_rpg_workspace(tmp_path): _sh(ws, "commit", "-q", "-m", "init") # Seed RPG without meta.git (so we can verify it gets set) - data_dir = ws / ".rpgkit" / "data" + data_dir = ws / ".cmind" / "data" data_dir.mkdir(parents=True) rpg_path = data_dir / "rpg.json" dep_graph_path = data_dir / "dep_graph.json" diff --git a/CoderMind/tests/test_storage.py b/CoderMind/tests/test_storage.py index 9d04eb6..845b89c 100644 --- a/CoderMind/tests/test_storage.py +++ b/CoderMind/tests/test_storage.py @@ -1,4 +1,4 @@ -"""Unit tests for ``rpgkit_cli._storage``.""" +"""Unit tests for ``cmind_cli._storage``.""" from __future__ import annotations import sys @@ -8,12 +8,12 @@ # Make ``src/`` importable when running pytest directly from a clean # checkout (no ``pip install -e .`` step). Same pattern as the other -# rpgkit_cli unit tests in this directory. +# cmind_cli unit tests in this directory. _SRC_DIR = Path(__file__).resolve().parents[1] / "src" if str(_SRC_DIR) not in sys.path: sys.path.insert(0, str(_SRC_DIR)) -from rpgkit_cli import _storage # noqa: E402 +from cmind_cli import _storage # noqa: E402 # --------------------------------------------------------------------------- @@ -121,7 +121,7 @@ def test_home_workspace_dir_under_home_root( self, fake_home: Path, workspace: Path ) -> None: d = _storage.home_workspace_dir(workspace) - assert d.is_relative_to(fake_home / ".rpgkit" / "workspaces") + assert d.is_relative_to(fake_home / ".cmind" / "workspaces") assert d.name == _storage.workspace_id(workspace) def test_data_logs_inner_git_under_home( @@ -137,7 +137,7 @@ def test_reports_dir_under_workspace( ) -> None: """Reports stay in the workspace, not in home.""" reports = _storage.workspace_reports_dir(workspace) - assert reports == workspace.resolve() / ".rpgkit" / "reports" + assert reports == workspace.resolve() / ".cmind" / "reports" def test_legacy_hash_dir_fallback( self, fake_home: Path, workspace: Path @@ -150,7 +150,7 @@ def test_legacy_hash_dir_fallback( """ # Plant a legacy directory but **no** slug-named one. legacy_dir = ( - fake_home / ".rpgkit" / "workspaces" / _storage._legacy_workspace_id(workspace) + fake_home / ".cmind" / "workspaces" / _storage._legacy_workspace_id(workspace) ) legacy_dir.mkdir(parents=True) assert _storage.home_workspace_dir(workspace) == legacy_dir @@ -161,14 +161,14 @@ def test_slug_dir_wins_over_legacy( """When both legacy and slug dirs exist, the slug dir wins. Lets users migrate by simply creating the slug dir (or letting - the next ``rpgkit init`` do it) without manual cleanup. + the next ``cmind init`` do it) without manual cleanup. """ legacy_dir = ( - fake_home / ".rpgkit" / "workspaces" / _storage._legacy_workspace_id(workspace) + fake_home / ".cmind" / "workspaces" / _storage._legacy_workspace_id(workspace) ) legacy_dir.mkdir(parents=True) slug_dir = ( - fake_home / ".rpgkit" / "workspaces" / _storage.workspace_id(workspace) + fake_home / ".cmind" / "workspaces" / _storage.workspace_id(workspace) ) slug_dir.mkdir(parents=True) assert _storage.home_workspace_dir(workspace) == slug_dir @@ -181,8 +181,8 @@ def test_slug_dir_wins_over_legacy( class TestFindWorkspaceRoot: def _mark(self, ws: Path) -> None: """Plant the workspace marker file.""" - (ws / ".rpgkit").mkdir(exist_ok=True) - (ws / ".rpgkit" / "config.toml").write_text("ai = 'claude'\n") + (ws / ".cmind").mkdir(exist_ok=True) + (ws / ".cmind" / "config.toml").write_text("ai = 'claude'\n") def test_finds_at_root(self, workspace: Path) -> None: self._mark(workspace) @@ -216,14 +216,14 @@ def test_skips_stale_marker_with_mismatched_meta( renamed) and the walker keeps climbing rather than misrouting.""" self._mark(workspace) # Forge meta recording a *different* absolute path under - # ``~/.rpgkit/workspaces//.meta.toml``. + # ``~/.cmind/workspaces//.meta.toml``. meta_path = _storage.workspace_meta_path(workspace) meta_path.parent.mkdir(parents=True, exist_ok=True) meta_path.write_text( 'channel = "bundle"\n' f'workspace_path = "{workspace.parent / "elsewhere"}"\n' - 'rpgkit_cli_version_at_init = "0.1.4"\n' - 'rpgkit_cli_version_last_seen = "0.1.4"\n' + 'cmind_cli_version_at_init = "0.1.4"\n' + 'cmind_cli_version_last_seen = "0.1.4"\n' 'initialised_at = "2026-01-01T00:00:00+00:00"\n' ) assert _storage.find_workspace_root_from(workspace) is None @@ -245,14 +245,14 @@ def test_write_then_read_roundtrip( _storage.write_meta( workspace, channel=_storage.CHANNEL_BUNDLE, - rpgkit_cli_version="0.1.4", + cmind_cli_version="0.1.4", ) data = _storage.read_meta(workspace) assert data is not None assert data["channel"] == "bundle" assert data["workspace_path"] == str(workspace.resolve()) - assert data["rpgkit_cli_version_at_init"] == "0.1.4" - assert data["rpgkit_cli_version_last_seen"] == "0.1.4" + assert data["cmind_cli_version_at_init"] == "0.1.4" + assert data["cmind_cli_version_last_seen"] == "0.1.4" assert "created_at" in data assert "last_seen_at" in data @@ -317,24 +317,24 @@ def test_reset_resets_init_version( _storage.write_meta( workspace, channel=_storage.CHANNEL_BUNDLE, - rpgkit_cli_version="0.1.4", + cmind_cli_version="0.1.4", ) first = _storage.read_meta(workspace) assert first is not None - assert first["rpgkit_cli_version_at_init"] == "0.1.4" + assert first["cmind_cli_version_at_init"] == "0.1.4" _storage.write_meta( workspace, channel=_storage.CHANNEL_BUNDLE, - rpgkit_cli_version="0.2.0", + cmind_cli_version="0.2.0", preserve_created_at=False, ) second = _storage.read_meta(workspace) assert second is not None # init_version should track the *current* call now, not the # previously-recorded one. - assert second["rpgkit_cli_version_at_init"] == "0.2.0" - assert second["rpgkit_cli_version_last_seen"] == "0.2.0" + assert second["cmind_cli_version_at_init"] == "0.2.0" + assert second["cmind_cli_version_last_seen"] == "0.2.0" # --------------------------------------------------------------------------- @@ -402,8 +402,8 @@ class TestResolveDataFromCwd: def test_resolves_from_subdir( self, fake_home: Path, workspace: Path, monkeypatch: pytest.MonkeyPatch ) -> None: - (workspace / ".rpgkit").mkdir() - (workspace / ".rpgkit" / "config.toml").write_text("") + (workspace / ".cmind").mkdir() + (workspace / ".cmind" / "config.toml").write_text("") sub = workspace / "src" sub.mkdir() monkeypatch.chdir(sub) diff --git a/CoderMind/tests/test_sync_from_commit_diff.py b/CoderMind/tests/test_sync_from_commit_diff.py index a6bf279..9024078 100644 --- a/CoderMind/tests/test_sync_from_commit_diff.py +++ b/CoderMind/tests/test_sync_from_commit_diff.py @@ -88,7 +88,7 @@ def synced_repo(tmp_path): head = _head_sha(repo) # Build the RPG fresh and seed meta.git so we're at "in sync". - data_dir = repo / ".rpgkit" / "data" + data_dir = repo / ".cmind" / "data" data_dir.mkdir(parents=True) rpg_path = data_dir / "rpg.json" dep_graph_path = data_dir / "dep_graph.json" @@ -145,7 +145,7 @@ def test_first_sync_runs_full(tmp_path): _sh(repo, "add", ".") _sh(repo, "commit", "-q", "-m", "c1") - data_dir = repo / ".rpgkit" / "data" + data_dir = repo / ".cmind" / "data" data_dir.mkdir(parents=True) rpg_path = data_dir / "rpg.json" dep_graph_path = data_dir / "dep_graph.json" @@ -291,7 +291,7 @@ def test_over_limit_falls_back_to_full(synced_repo, monkeypatch): def test_no_git_meta_env_var_skips_meta_write(synced_repo, monkeypatch): - """``RPGKIT_NO_GIT_META=1`` must not advance ``meta.git``.""" + """``CMIND_NO_GIT_META=1`` must not advance ``meta.git``.""" repo, rpg_path, dep_graph_path, code, original_head = synced_repo # Make a real commit so HEAD changes @@ -300,7 +300,7 @@ def test_no_git_meta_env_var_skips_meta_write(synced_repo, monkeypatch): _sh(repo, "commit", "-q", "-m", "y") new_head = _head_sha(repo) - monkeypatch.setenv("RPGKIT_NO_GIT_META", "1") + monkeypatch.setenv("CMIND_NO_GIT_META", "1") svc = _load(rpg_path) result = svc.sync_from_commit_diff( code_dir=str(code), @@ -448,7 +448,7 @@ def test_sync_from_file_list_bootstraps_full_when_no_dep_graph(tmp_path): _sh(repo, "add", ".") _sh(repo, "commit", "-q", "-m", "c1") - data_dir = repo / ".rpgkit" / "data" + data_dir = repo / ".cmind" / "data" data_dir.mkdir(parents=True) rpg_path = data_dir / "rpg.json" dep_graph_path = data_dir / "dep_graph.json" @@ -525,7 +525,7 @@ def test_cli_sync_force_full(synced_repo): def test_cli_sync_missing_rpg_returns_actionable_error(tmp_path): - """``sync`` must early-return with a /rpgkit.encode hint when rpg.json is absent. + """``sync`` must early-return with a /cmind.encode hint when rpg.json is absent. Regression guard: previously ``RPGService.load`` raised ``FileNotFoundError`` which the post-commit hook silently swallowed @@ -549,5 +549,5 @@ def test_cli_sync_missing_rpg_returns_actionable_error(tmp_path): payload = json.loads(result.stdout) assert payload["mode"] == sub assert "error" in payload, payload - assert "/rpgkit.encode" in payload["error"], payload["error"] + assert "/cmind.encode" in payload["error"], payload["error"] assert str(missing) in payload["error"] diff --git a/CoderMind/tests/test_workflow_integration.py b/CoderMind/tests/test_workflow_integration.py index 3c4faa1..614fd68 100644 --- a/CoderMind/tests/test_workflow_integration.py +++ b/CoderMind/tests/test_workflow_integration.py @@ -2,7 +2,7 @@ """Tests for M13 Workflow Integration. Covers: - - RPGKitConfig: load from YAML, from_dict, defaults, validation, save + - CMindConfig: load from YAML, from_dict, defaults, validation, save - RPGVersionControl: save_version, rollback, diff, list_versions, pruning - WorkflowIntegration: prepare_for_codegen, merge_generated_code, save_rpg, load_rpg, detect_workflow_mode @@ -38,13 +38,13 @@ uuid8, ) from rpg_encoder.config import ( - RPGKitConfig, + CMindConfig, WorkflowConfig, EncodeConfig, CodegenConfig, VersioningConfig, CONFIG_FILE_NAME, - RPGKIT_DIR_NAME, + CMIND_DIR_NAME, _parse_workflow, ) from rpg_encoder.version_control import ( @@ -133,25 +133,25 @@ def simple_rpg(): @pytest.fixture -def tmp_rpgkit_dir(): - """Create a temporary .rpgkit directory.""" +def tmp_cmind_dir(): + """Create a temporary .cmind directory.""" with tempfile.TemporaryDirectory() as tmpdir: - rpgkit_dir = os.path.join(tmpdir, RPGKIT_DIR_NAME) - os.makedirs(rpgkit_dir, exist_ok=True) - yield tmpdir, rpgkit_dir + cmind_dir = os.path.join(tmpdir, CMIND_DIR_NAME) + os.makedirs(cmind_dir, exist_ok=True) + yield tmpdir, cmind_dir # ============================================================================ -# Tests: RPGKitConfig +# Tests: CMindConfig # ============================================================================ -class TestRPGKitConfig: +class TestCMindConfig: """Tests for the configuration module.""" def test_default_config(self): """Default config has expected values.""" - config = RPGKitConfig() + config = CMindConfig() assert config.workflow.default_mode == "mixed" assert config.workflow.encode.auto_exclude == ["tests/", "docs/"] assert config.workflow.encode.run_data_flow is False @@ -179,7 +179,7 @@ def test_from_dict_full(self): }, } } - config = RPGKitConfig.from_dict(data) + config = CMindConfig.from_dict(data) assert config.workflow.default_mode == "forward" assert config.workflow.encode.auto_exclude == ["vendor/"] assert config.workflow.encode.run_data_flow is True @@ -191,7 +191,7 @@ def test_from_dict_full(self): def test_from_dict_partial(self): """Missing keys use defaults.""" data = {"workflow": {"default_mode": "reverse"}} - config = RPGKitConfig.from_dict(data) + config = CMindConfig.from_dict(data) assert config.workflow.default_mode == "reverse" # Defaults for sub-configs assert config.workflow.encode.auto_exclude == ["tests/", "docs/"] @@ -199,18 +199,18 @@ def test_from_dict_partial(self): def test_from_dict_empty(self): """Empty dict gives full defaults.""" - config = RPGKitConfig.from_dict({}) + config = CMindConfig.from_dict({}) assert config.workflow.default_mode == "mixed" def test_invalid_default_mode_falls_back(self): """Invalid default_mode falls back to 'mixed'.""" data = {"workflow": {"default_mode": "invalid_mode"}} - config = RPGKitConfig.from_dict(data) + config = CMindConfig.from_dict(data) assert config.workflow.default_mode == "mixed" def test_to_dict_roundtrip(self): """to_dict produces data that from_dict can consume back.""" - original = RPGKitConfig.from_dict({ + original = CMindConfig.from_dict({ "workflow": { "default_mode": "forward", "encode": {"auto_exclude": ["build/"]}, @@ -218,21 +218,21 @@ def test_to_dict_roundtrip(self): } }) exported = original.to_dict() - restored = RPGKitConfig.from_dict(exported) + restored = CMindConfig.from_dict(exported) assert restored.workflow.default_mode == "forward" assert restored.workflow.encode.auto_exclude == ["build/"] assert restored.workflow.versioning.max_history == 20 - def test_load_with_yaml_file(self, tmp_rpgkit_dir): - """Config.load reads from .rpgkit/config.yaml.""" - repo_dir, rpgkit_dir = tmp_rpgkit_dir + def test_load_with_yaml_file(self, tmp_cmind_dir): + """Config.load reads from .cmind/config.yaml.""" + repo_dir, cmind_dir = tmp_cmind_dir config_content = { "workflow": { "default_mode": "reverse", "versioning": {"max_history": 3}, } } - config_path = os.path.join(rpgkit_dir, CONFIG_FILE_NAME) + config_path = os.path.join(cmind_dir, CONFIG_FILE_NAME) try: import yaml with open(config_path, "w") as f: @@ -240,34 +240,34 @@ def test_load_with_yaml_file(self, tmp_rpgkit_dir): except ImportError: pytest.skip("PyYAML not installed") - config = RPGKitConfig.load(repo_dir) + config = CMindConfig.load(repo_dir) assert config.workflow.default_mode == "reverse" assert config.workflow.versioning.max_history == 3 assert config.config_path == config_path - def test_load_no_file_gives_defaults(self, tmp_rpgkit_dir): + def test_load_no_file_gives_defaults(self, tmp_cmind_dir): """Config.load returns defaults when no config file exists.""" - repo_dir, _ = tmp_rpgkit_dir - config = RPGKitConfig.load(repo_dir) + repo_dir, _ = tmp_cmind_dir + config = CMindConfig.load(repo_dir) assert config.workflow.default_mode == "mixed" assert config.config_path is None - def test_save_and_load(self, tmp_rpgkit_dir): + def test_save_and_load(self, tmp_cmind_dir): """save() creates a YAML file that load() can read.""" - repo_dir, rpgkit_dir = tmp_rpgkit_dir + repo_dir, cmind_dir = tmp_cmind_dir try: import yaml except ImportError: pytest.skip("PyYAML not installed") - config = RPGKitConfig.from_dict( + config = CMindConfig.from_dict( {"workflow": {"default_mode": "forward"}}, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, ) saved_path = config.save() assert os.path.isfile(saved_path) - loaded = RPGKitConfig.load(repo_dir) + loaded = CMindConfig.load(repo_dir) assert loaded.workflow.default_mode == "forward" def test_parse_workflow_none(self): @@ -295,10 +295,10 @@ def test_parse_version_from_filename(self): assert _parse_version_from_filename("other.txt") is None assert _parse_version_from_filename("rpg.vabc.json") is None - def test_save_and_list(self, simple_rpg, tmp_rpgkit_dir): + def test_save_and_list(self, simple_rpg, tmp_cmind_dir): """save_version creates files; list_versions enumerates them.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir, max_history=10) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir, max_history=10) v1 = vc.save_version(simple_rpg, message="First version") assert v1 == 1 @@ -312,39 +312,39 @@ def test_save_and_list(self, simple_rpg, tmp_rpgkit_dir): assert versions[0]["message"] == "First version" assert versions[1]["version"] == 2 - def test_save_with_source(self, simple_rpg, tmp_rpgkit_dir): + def test_save_with_source(self, simple_rpg, tmp_cmind_dir): """save_version stores source metadata.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) vc.save_version(simple_rpg, message="Encoded", source="encoded") versions = vc.list_versions() assert versions[0]["source"] == "encoded" - def test_rollback(self, simple_rpg, tmp_rpgkit_dir): + def test_rollback(self, simple_rpg, tmp_cmind_dir): """Rollback loads RPG from a saved version.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) vc.save_version(simple_rpg, message="Original") restored = vc.rollback(version=1) assert isinstance(restored, RPG) assert restored.repo_name == "test_repo" # Check that main rpg.json was also written - main_rpg = os.path.join(rpgkit_dir, "data", "rpg.json") + main_rpg = os.path.join(cmind_dir, "data", "rpg.json") assert os.path.isfile(main_rpg) - def test_rollback_nonexistent_raises(self, tmp_rpgkit_dir): + def test_rollback_nonexistent_raises(self, tmp_cmind_dir): """Rollback raises FileNotFoundError for missing versions.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) with pytest.raises(FileNotFoundError): vc.rollback(version=999) - def test_diff_nodes(self, tmp_rpgkit_dir): + def test_diff_nodes(self, tmp_cmind_dir): """Diff detects added/removed nodes between versions.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) # Version 1: small RPG rpg1 = RPG(repo_name="test") @@ -366,10 +366,10 @@ def test_diff_nodes(self, tmp_rpgkit_dir): assert "extra_node" in diff["nodes_added"] assert diff["summary"]["nodes_added"] >= 1 - def test_diff_edges(self, tmp_rpgkit_dir): + def test_diff_edges(self, tmp_cmind_dir): """Diff detects added/removed non-containment edges.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) rpg1 = RPG(repo_name="test") n1 = Node(id="n1", name="A", level=None) @@ -394,17 +394,17 @@ def test_diff_edges(self, tmp_rpgkit_dir): diff = vc.diff(1, 2) assert diff["summary"]["edges_added"] >= 1 - def test_diff_nonexistent_raises(self, tmp_rpgkit_dir): + def test_diff_nonexistent_raises(self, tmp_cmind_dir): """Diff raises FileNotFoundError for missing versions.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) with pytest.raises(FileNotFoundError): vc.diff(1, 2) - def test_max_history_prunes(self, simple_rpg, tmp_rpgkit_dir): + def test_max_history_prunes(self, simple_rpg, tmp_cmind_dir): """save_version prunes old versions when max_history is exceeded.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir, max_history=3) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir, max_history=3) for i in range(5): vc.save_version(simple_rpg, message=f"Version {i+1}") @@ -414,10 +414,10 @@ def test_max_history_prunes(self, simple_rpg, tmp_rpgkit_dir): # Oldest versions should have been pruned assert versions[0]["version"] == 3 - def test_get_latest_version(self, simple_rpg, tmp_rpgkit_dir): + def test_get_latest_version(self, simple_rpg, tmp_cmind_dir): """get_latest_version returns the highest version number.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) assert vc.get_latest_version() is None vc.save_version(simple_rpg, message="V1") @@ -426,10 +426,10 @@ def test_get_latest_version(self, simple_rpg, tmp_rpgkit_dir): vc.save_version(simple_rpg, message="V2") assert vc.get_latest_version() == 2 - def test_list_versions_empty_dir(self, tmp_rpgkit_dir): + def test_list_versions_empty_dir(self, tmp_cmind_dir): """list_versions returns empty list for fresh directory.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) assert vc.list_versions() == [] @@ -620,46 +620,46 @@ def test_merge_generated_code_invalid_syntax(self, simple_rpg): # Should not crash; may or may not add the file depending on parser assert isinstance(updated, RPG) - def test_save_rpg(self, simple_rpg, tmp_rpgkit_dir): + def test_save_rpg(self, simple_rpg, tmp_cmind_dir): """save_rpg writes to disk and creates a version.""" - _, rpgkit_dir = tmp_rpgkit_dir + _, cmind_dir = tmp_cmind_dir result = WorkflowIntegration.save_rpg( rpg=simple_rpg, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, message="Test save", source="encoded", ) assert os.path.isfile(result["rpg_path"]) assert "version" in result - def test_save_rpg_without_versioning(self, simple_rpg, tmp_rpgkit_dir): + def test_save_rpg_without_versioning(self, simple_rpg, tmp_cmind_dir): """save_rpg with version_control=False skips versioning.""" - _, rpgkit_dir = tmp_rpgkit_dir + _, cmind_dir = tmp_cmind_dir result = WorkflowIntegration.save_rpg( rpg=simple_rpg, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, message="No version", version_control=False, ) assert os.path.isfile(result["rpg_path"]) assert "version" not in result - def test_load_rpg(self, simple_rpg, tmp_rpgkit_dir): + def test_load_rpg(self, simple_rpg, tmp_cmind_dir): """load_rpg reads RPG from saved file.""" - _, rpgkit_dir = tmp_rpgkit_dir + _, cmind_dir = tmp_cmind_dir WorkflowIntegration.save_rpg( rpg=simple_rpg, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, version_control=False, ) - loaded = WorkflowIntegration.load_rpg(rpgkit_dir) + loaded = WorkflowIntegration.load_rpg(cmind_dir) assert loaded is not None assert loaded.repo_name == "test_repo" - def test_load_rpg_nonexistent(self, tmp_rpgkit_dir): + def test_load_rpg_nonexistent(self, tmp_cmind_dir): """load_rpg returns None when file doesn't exist.""" - _, rpgkit_dir = tmp_rpgkit_dir - loaded = WorkflowIntegration.load_rpg(rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + loaded = WorkflowIntegration.load_rpg(cmind_dir) assert loaded is None def test_detect_workflow_mode_no_rpg(self): @@ -783,21 +783,21 @@ def test_infer_rpg_source_no_generators(self): class TestWorkflowScenarios: """Integration tests for the four workflow scenarios.""" - def test_pure_reverse_scenario(self, simple_rpg, tmp_rpgkit_dir): + def test_pure_reverse_scenario(self, simple_rpg, tmp_cmind_dir): """Pure reverse: encode -> save -> load -> explore.""" - _, rpgkit_dir = tmp_rpgkit_dir + _, cmind_dir = tmp_cmind_dir # Save the encoded RPG result = WorkflowIntegration.save_rpg( rpg=simple_rpg, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, message="Encoded from repo", source="encoded", ) assert result["version"] == 1 # Load it back - loaded = WorkflowIntegration.load_rpg(rpgkit_dir) + loaded = WorkflowIntegration.load_rpg(cmind_dir) assert loaded is not None assert loaded.repo_name == "test_repo" @@ -805,14 +805,14 @@ def test_pure_reverse_scenario(self, simple_rpg, tmp_rpgkit_dir): context = WorkflowIntegration.prepare_for_codegen(rpg=loaded) assert context["source"] == "encoded" - def test_mixed_enhance_scenario(self, simple_rpg, tmp_rpgkit_dir): + def test_mixed_enhance_scenario(self, simple_rpg, tmp_cmind_dir): """Mixed: encode -> save -> merge new code -> save.""" - _, rpgkit_dir = tmp_rpgkit_dir + _, cmind_dir = tmp_cmind_dir # Step 1: Save encoded RPG WorkflowIntegration.save_rpg( rpg=simple_rpg, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, message="Initial encode", source="encoded", ) @@ -834,21 +834,21 @@ def test_mixed_enhance_scenario(self, simple_rpg, tmp_rpgkit_dir): # Step 4: Save updated RPG result = WorkflowIntegration.save_rpg( rpg=updated, - rpgkit_dir=rpgkit_dir, + cmind_dir=cmind_dir, message="Added helper module", source="mixed", ) assert result["version"] == 2 # Verify version history - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + vc = RPGVersionControl(cmind_dir=cmind_dir) versions = vc.list_versions() assert len(versions) == 2 - def test_iterative_scenario(self, simple_rpg, tmp_rpgkit_dir): + def test_iterative_scenario(self, simple_rpg, tmp_cmind_dir): """Iterative: merge -> save -> merge -> save -> diff.""" - _, rpgkit_dir = tmp_rpgkit_dir - vc = RPGVersionControl(rpgkit_dir=rpgkit_dir) + _, cmind_dir = tmp_cmind_dir + vc = RPGVersionControl(cmind_dir=cmind_dir) # Iteration 1 vc.save_version(simple_rpg, message="Before iteration 1") diff --git a/CoderMind/tests/test_workspace_unified_layout.py b/CoderMind/tests/test_workspace_unified_layout.py index d9774b9..e2ff42b 100644 --- a/CoderMind/tests/test_workspace_unified_layout.py +++ b/CoderMind/tests/test_workspace_unified_layout.py @@ -41,7 +41,7 @@ def _reload_paths_against(workspace: Path): reload. """ os.chdir(workspace) - os.environ.pop("RPGKIT_WORKSPACE", None) + os.environ.pop("CMIND_WORKSPACE", None) import common.paths as paths_mod importlib.reload(paths_mod) return paths_mod @@ -51,9 +51,9 @@ def _reload_paths_against(workspace: Path): def workspace(tmp_path, monkeypatch): ws = tmp_path / "ws" ws.mkdir() - (ws / ".rpgkit").mkdir() + (ws / ".cmind").mkdir() monkeypatch.chdir(ws) - monkeypatch.delenv("RPGKIT_WORKSPACE", raising=False) + monkeypatch.delenv("CMIND_WORKSPACE", raising=False) return ws @@ -66,12 +66,12 @@ def workspace_with_unrelated_repo_subdir(tmp_path, monkeypatch): """ ws = tmp_path / "ws_with_repo" ws.mkdir() - (ws / ".rpgkit").mkdir() + (ws / ".cmind").mkdir() (ws / "repo").mkdir() (ws / "repo" / "stale.py").write_text("# legacy / unrelated\n") (ws / "auth.py").write_text("def login(): pass\n") monkeypatch.chdir(ws) - monkeypatch.delenv("RPGKIT_WORKSPACE", raising=False) + monkeypatch.delenv("CMIND_WORKSPACE", raising=False) return ws @@ -266,7 +266,7 @@ def test_run_batch_preserves_external_surface(monkeypatch): ``dispatch_sub_agent`` """ monkeypatch.chdir(_project_root) # avoid stale cwd from previous fixtures - monkeypatch.delenv("RPGKIT_WORKSPACE", raising=False) + monkeypatch.delenv("CMIND_WORKSPACE", raising=False) import run_batch required = ( "REPO_RPG_FILE", diff --git a/CoderMind/utils/build_dep_graph.py b/CoderMind/utils/build_dep_graph.py index 4343c82..7de5932 100644 --- a/CoderMind/utils/build_dep_graph.py +++ b/CoderMind/utils/build_dep_graph.py @@ -8,8 +8,8 @@ Usage: python3 utils/build_dep_graph.py \ --repo-dir ./repo \ - --rpg-in .rpgkit/data/repo_rpg.json \ - --rpg-out .rpgkit/data/rpg.json + --rpg-in .cmind/data/repo_rpg.json \ + --rpg-out .cmind/data/rpg.json """ import argparse @@ -144,7 +144,7 @@ def _filter_build(file_id: str) -> bool: ".git", "__pycache__", "node_modules", ".venv", "venv", ".idea", ".vscode", ".pytest_cache", ".mypy_cache", "build", "dist", - ".rpgkit", ".venv_dev", + ".cmind", ".venv_dev", } FILE_BL = { "Makefile", "CMakeLists.txt", "Dockerfile", diff --git a/CoderMind/utils/rpg_stats.py b/CoderMind/utils/rpg_stats.py index 0e1fdb4..5e2c254 100644 --- a/CoderMind/utils/rpg_stats.py +++ b/CoderMind/utils/rpg_stats.py @@ -1,18 +1,18 @@ #!/usr/bin/env python3 """ -RPG-Kit Usage Statistics & Report Generator +CoderMind Usage Statistics & Report Generator -Reads JSONL telemetry logs from .rpgkit/logs/ and generates usage reports. +Reads JSONL telemetry logs from .cmind/logs/ and generates usage reports. Usage: python utils/rpg_stats.py # print summary to stdout - python utils/rpg_stats.py --report # write markdown report to .rpgkit/reports/ + python utils/rpg_stats.py --report # write markdown report to .cmind/reports/ python utils/rpg_stats.py --json # print summary as JSON python utils/rpg_stats.py --days 7 # only last 7 days Log files consumed: - .rpgkit/logs/mcp_calls.jsonl — MCP tool invocations (search, explore, etc.) - .rpgkit/logs/hook_calls.jsonl — git hook invocations (sync, update-rpg) + .cmind/logs/mcp_calls.jsonl — MCP tool invocations (search, explore, etc.) + .cmind/logs/hook_calls.jsonl — git hook invocations (sync, update-rpg) """ import argparse @@ -34,9 +34,9 @@ except ImportError: # Fallback for standalone usage _WS = Path.cwd() - MCP_CALLS_LOG = _WS / ".rpgkit" / "logs" / "mcp_calls.jsonl" - HOOK_CALLS_LOG = _WS / ".rpgkit" / "logs" / "hook_calls.jsonl" - REPORTS_DIR = _WS / ".rpgkit" / "reports" + MCP_CALLS_LOG = _WS / ".cmind" / "logs" / "mcp_calls.jsonl" + HOOK_CALLS_LOG = _WS / ".cmind" / "logs" / "hook_calls.jsonl" + REPORTS_DIR = _WS / ".cmind" / "reports" def _read_jsonl(path: Path, since: Optional[datetime] = None) -> List[dict]: @@ -144,7 +144,7 @@ def generate_report(mcp_stats: dict, hook_stats: dict, days: Optional[int] = Non """Generate a Markdown usage report.""" period = f"last {days} days" if days else "all time" lines = [ - f"# RPG-Kit Usage Report", + f"# CoderMind Usage Report", f"", f"Period: **{period}**", f"Generated: {datetime.now().strftime('%Y-%m-%d %H:%M')}", @@ -210,9 +210,9 @@ def generate_report(mcp_stats: dict, hook_stats: dict, days: Optional[int] = Non def main(): - parser = argparse.ArgumentParser(description="RPG-Kit usage statistics") + parser = argparse.ArgumentParser(description="CoderMind usage statistics") parser.add_argument("--report", action="store_true", - help="Write Markdown report to .rpgkit/reports/") + help="Write Markdown report to .cmind/reports/") parser.add_argument("--json", action="store_true", help="Output raw stats as JSON") parser.add_argument("--days", type=int, default=None, diff --git a/README.md b/README.md index bae6853..4a5c898 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ > [!NOTE] > **CoderMind** is the new name for **RPG-Kit**. The product has been renamed; the install command (`rpgkit`) and package (`rpgkit-cli`) will be renamed in a subsequent release. -🔥 **New: [CoderMind](CoderMind/) (formerly RPG-Kit) is now open source for Claude Code and GitHub Copilot.** +🔥 **New: [CoderMind](CoderMind/) is now open source for Claude Code and GitHub Copilot.** Coding agents often lose repository-level context across long tasks: requirements drift, architecture decisions disappear, and edits miss hidden dependencies. @@ -24,7 +24,7 @@ The repository also includes the research code: **[ZeroRepo](#zerorepo-requireme ## News -- [2026-05-15] 🚀 **CoderMind** (formerly RPG-Kit) is now open source for Claude Code and GitHub Copilot. It uses Repository Planning Graphs as a control layer for long-horizon coding agents, including planning, multi-file generation, repository understanding, and graph-aware updates. +- [2026-05-15] 🚀 **CoderMind** is now open source for Claude Code and GitHub Copilot. It uses Repository Planning Graphs as a control layer for long-horizon coding agents, including planning, multi-file generation, repository understanding, and graph-aware updates. - [2026-05-01] 🎉 **RPG-Encoder** ([*Closing the Loop: Universal Repository Representation with RPG-Encoder*](https://arxiv.org/abs/2602.02084)) has been accepted to **ICML 2026**. - [2026-03-02] 🚀 We have open-sourced the **EpiCoder Feature Tree** at [Hugging Face](https://huggingface.co/datasets/microsoft/EpiCoder-meta-features), providing structured knowledge for repository planning in **ZeroRepo**. - [2026-02-27] 🚀 We released the code for [RPG-Encoder](zerorepo/rpg_encoder/) and [RepoCraft](repocraft/). @@ -73,33 +73,33 @@ Coding agents are strong at local edits, but repository-level work requires dura |---|---|---|---| | **Build a new repository** | A natural-language requirement | Create an RPG plan, refine it into architecture/tasks, then generate code. | A persistent plan for long-horizon multi-file generation. | | **Understand an existing repository** | An existing codebase | Encode the repo into an RPG workspace, then search, explore, and explain through MCP tools (`search_rpg`, `explore_rpg`, `get_node_detail`). | A structured repository map beyond chat history and file search. | -| **Update an existing repository** | A codebase + change request | Use the RPG to locate affected nodes, plan the edit, and update code and graph together (`/rpgkit.rpg_edit "..."`). | Graph-aware edits that account for cross-file dependencies. | +| **Update an existing repository** | A codebase + change request | Use the RPG to locate affected nodes, plan the edit, and update code and graph together (`/cmind.rpg_edit "..."`). | Graph-aware edits that account for cross-file dependencies. | ### Quick Start ```bash -uv tool install rpgkit-cli \ +uv tool install cmind-cli \ --from "git+https://github.com/microsoft/RPG-ZeroRepo.git#subdirectory=CoderMind" -rpgkit check +cmind check ``` **On an existing repository:** ```bash cd your-existing-repo -rpgkit init . --encode +cmind init . --encode # In Claude Code or GitHub Copilot: -# /rpgkit.rpg_edit "Add rate limiting to all API endpoints" +# /cmind.rpg_edit "Add rate limiting to all API endpoints" ``` **Generate a new repository:** ```bash -rpgkit init my-project +cmind init my-project cd my-project # In Claude Code or GitHub Copilot: -# /rpgkit.feature_spec Build a CLI tool for managing Docker containers -# /rpgkit.feature_build → /rpgkit.feature_refactor → ... → /rpgkit.code_gen +# /cmind.feature_spec Build a CLI tool for managing Docker containers +# /cmind.feature_build → /cmind.feature_refactor → ... → /cmind.code_gen ``` See [`CoderMind/README.md`](CoderMind/README.md) for the full setup, slash commands, and MCP tools. @@ -111,8 +111,8 @@ CoderMind gives Claude Code and GitHub Copilot a **persistent RPG workspace** fo CoderMind exposes the RPG workspace through three interfaces: -- **CLI setup** — initialize CoderMind in a new or existing repository with `rpgkit init`. -- **Slash commands** — run build, understand, and update workflows inside the coding agent (`/rpgkit.feature_spec`, `/rpgkit.code_gen`, `/rpgkit.encode`, `/rpgkit.rpg_edit`, and more). +- **CLI setup** — initialize CoderMind in a new or existing repository with `cmind init`. +- **Slash commands** — run build, understand, and update workflows inside the coding agent (`/cmind.feature_spec`, `/cmind.code_gen`, `/cmind.encode`, `/cmind.rpg_edit`, and more). - **MCP graph tools** — let the agent search, inspect, and traverse RPG nodes during coding (`search_rpg`, `explore_rpg`, `get_node_detail`, `list_rpg_tree`). CoderMind can keep the RPG in sync with code changes through a post-commit hook, so edits made by the agent or directly in code can be reflected back into the graph. @@ -121,9 +121,9 @@ CoderMind can keep the RPG in sync with code changes through a post-commit hook, ### CoderMind in action -The graph below was produced by running `/rpgkit.encode` on this repository: +The graph below was produced by running `/cmind.encode` on this repository: -![RPG visualization of this repository](docs/rpgkit_visualized_graph.png) +![RPG visualization of this repository](docs/cmind_visualized_graph.png) This illustrates how CoderMind turns an existing repository into an RPG that agents can search, explore, and use for graph-aware edits. diff --git a/docs/rpgkit_visualized_graph.png b/docs/cmind_visualized_graph.png similarity index 100% rename from docs/rpgkit_visualized_graph.png rename to docs/cmind_visualized_graph.png From efbf1623a6c7973c31a132addf12c35b4f851252 Mon Sep 17 00:00:00 2001 From: Yasen Hu <74404492+HuYaSen@users.noreply.github.com> Date: Thu, 28 May 2026 18:33:18 +0800 Subject: [PATCH 2/3] fix(cmind): address PR #60 review feedback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Surface fixes from Copilot review on the rename PR. Each item is either a real correctness issue (gitignore negation, broken slash command name, stale workspace inference) or a latent bug exposed by the rename. Changes: * gitignore: switch from '.cmind/' (whole-dir ignore) to '.cmind/*' (glob) so the '!.cmind/config.toml' negation actually applies — git does not descend into a directory ignored as a whole. Same fix applied to cmind_cli._GITIGNORE_CMIND_COMMON so new workspaces written by 'cmind init' inherit the correct pattern. * gitignore/dep_graph/smoke_test: also ignore (or skip during code discovery) legacy '.rpgkit/' directories so users upgrading from pre-rename workspaces don't accidentally commit stale runtime data or have it scanned by smoke tests / dependency-graph build. * Slash command name: correct '/cmind.refactor_feature' → '/cmind.feature_refactor' in three places (build_skeleton.md, check_skeleton.py, build_skeleton.py). Pre-existing typo, surfaced during the rename audit. * update_graphs.py workspace inference: the previous fallback walked up three levels from 'args.rpg' assuming a layout of '/.cmind/data/rpg.json'. After PR #56 moved the default rpg.json into the home-side store ('~/.cmind/workspaces//data/rpg.json'), that derivation produces the home directory, not the workspace. Replace it with 'cmind_cli._storage.find_workspace_root_from(cwd)' plus the 'CMIND_WORKSPACE' env var. The normal hook path is unaffected because '_hook_spawn_background' already 'cd's into the workspace before launching the worker, so cwd is correct and the fallback block is skipped entirely. * bm25_model docstring: 'an CoderMind dependency' → 'a CoderMind dependency' (article corrected post-rename). * rpg_visualize --help: point users at the home-side workspace store instead of the obsolete '/.cmind/data/rpg.json' path. * README.md: drop the now-stale '> [!NOTE] rpgkit/rpgkit-cli will be renamed in a subsequent release' callout — that subsequent release is this PR. Verification: * Re-installed cmind-cli locally and re-ran the e2e harness (encoder-hooks + encoder-mcp + encoder-encode + encoder-update_rpg) with --max-parallel 2: 4/4 stages PASS, 0 failures, total 371s. encoder-encode exercises the post-commit hook path through update_graphs.py, confirming the inference fallback change has no regression on the common code path. --- CoderMind/.gitignore | 7 ++++- CoderMind/scripts/build_skeleton.py | 2 +- CoderMind/scripts/check_skeleton.py | 2 +- CoderMind/scripts/rpg_agent/ops/bm25_model.py | 2 +- CoderMind/scripts/rpg_visualize.py | 2 +- CoderMind/scripts/smoke_test.py | 2 +- CoderMind/scripts/update_graphs.py | 31 ++++++++++++++++--- CoderMind/src/cmind_cli/__init__.py | 10 +++++- .../templates/commands/build_skeleton.md | 2 +- CoderMind/utils/build_dep_graph.py | 1 + README.md | 3 -- 11 files changed, 48 insertions(+), 16 deletions(-) diff --git a/CoderMind/.gitignore b/CoderMind/.gitignore index df54387..835fb40 100644 --- a/CoderMind/.gitignore +++ b/CoderMind/.gitignore @@ -225,10 +225,15 @@ plans/ .claude # CoderMind ignores (managed by `cmind init/update`) -.cmind/ +.cmind/* # But DO commit the workspace AI config so collaborators get a sane default. # Plan: plans/01-package-bundle-and-ai-config.md decision 15. +# (Must use `.cmind/*` above, not `.cmind/`, so this negation can take effect: +# git does not descend into a directory ignored as a whole.) !.cmind/config.toml +# Legacy runtime dir from pre-cmind workspaces — still ignored so old +# data doesn't accidentally get committed during upgrades. +.rpgkit/ .vscode/mcp.json .vscode/tasks.json .mcp.json diff --git a/CoderMind/scripts/build_skeleton.py b/CoderMind/scripts/build_skeleton.py index 0c2cc0c..d9b8554 100644 --- a/CoderMind/scripts/build_skeleton.py +++ b/CoderMind/scripts/build_skeleton.py @@ -624,7 +624,7 @@ def main(): if not input_path.exists(): logger.error(f"Input file not found: {input_path}") print(f"ERROR: Input file not found: {input_path}") - print("Please run /cmind.refactor_feature first.") + print("Please run /cmind.feature_refactor first.") return 1 try: diff --git a/CoderMind/scripts/check_skeleton.py b/CoderMind/scripts/check_skeleton.py index 59532eb..3f32304 100644 --- a/CoderMind/scripts/check_skeleton.py +++ b/CoderMind/scripts/check_skeleton.py @@ -325,7 +325,7 @@ def inspect_state() -> Dict[str, Any]: # Determine type and message if not input_valid: type_value = "error" - message = "Input file missing or invalid. Run /cmind.refactor_feature first." + message = "Input file missing or invalid. Run /cmind.feature_refactor first." elif not output_exists or not output_valid: type_value = "init" message = "Ready to build skeleton." diff --git a/CoderMind/scripts/rpg_agent/ops/bm25_model.py b/CoderMind/scripts/rpg_agent/ops/bm25_model.py index 15459e2..a95cec3 100644 --- a/CoderMind/scripts/rpg_agent/ops/bm25_model.py +++ b/CoderMind/scripts/rpg_agent/ops/bm25_model.py @@ -2,7 +2,7 @@ """BM25 Search Model for RPG Agent. Provides BM25-based retrieval for code entities and code content, -using `rank_bm25` (already an CoderMind dependency) instead of the +using `rank_bm25` (already a CoderMind dependency) instead of the heavier llama_index-based implementation in RPG-ZeroRepo. Ported from: RPG-ZeroRepo/zerorepo/rpg_encoder/rpg_agent/ops/bm25_model.py diff --git a/CoderMind/scripts/rpg_visualize.py b/CoderMind/scripts/rpg_visualize.py index 387367e..1d9d69b 100644 --- a/CoderMind/scripts/rpg_visualize.py +++ b/CoderMind/scripts/rpg_visualize.py @@ -1877,7 +1877,7 @@ def main(): parser = argparse.ArgumentParser(description="Visualize RPG as interactive graph") parser.add_argument("rpg_file", nargs="?", default=str(RPG_FILE), - help="Path to rpg.json (default: .cmind/data/rpg.json)") + help="Path to rpg.json (default: home-side workspace store at ~/.cmind/workspaces//data/rpg.json)") parser.add_argument("--dep-graph", default=None, help="Path to dep_graph.json (default: dep_graph_file field or sibling dep_graph.json)") parser.add_argument("-o", "--output", default=None, diff --git a/CoderMind/scripts/smoke_test.py b/CoderMind/scripts/smoke_test.py index e74bacf..35cc259 100644 --- a/CoderMind/scripts/smoke_test.py +++ b/CoderMind/scripts/smoke_test.py @@ -107,7 +107,7 @@ def _get_python_exe(repo_path: Path) -> str: def _find_source_files(repo_path: Path) -> List[Path]: """Find all .py source files (excluding tests, venv, __pycache__).""" skip_dirs = {".venv_dev", ".venv", "venv", "__pycache__", ".git", - ".cmind", ".pytest_cache", "node_modules"} + ".cmind", ".rpgkit", ".pytest_cache", "node_modules"} result = [] for py_file in repo_path.rglob("*.py"): parts = set(py_file.relative_to(repo_path).parts) diff --git a/CoderMind/scripts/update_graphs.py b/CoderMind/scripts/update_graphs.py index b970db2..5978c7f 100644 --- a/CoderMind/scripts/update_graphs.py +++ b/CoderMind/scripts/update_graphs.py @@ -818,12 +818,33 @@ def _add_common(p): workspace_root = os.getcwd() - # For background hook processes (setsid), cwd may not be the - # workspace root. Use the rpg file path to infer it: - # rpg_path = /.cmind/data/rpg.json → workspace = rpg_path/../../../ + # For background hook processes (setsid) or any caller whose cwd is + # not the workspace root, infer the workspace. Earlier versions of + # this fallback walked up from ``args.rpg`` assuming a layout of + # ``/.cmind/data/rpg.json``, which became wrong once the + # default ``rpg.json`` moved into the home-side store + # (``~/.cmind/workspaces//data/rpg.json``) in v0.1.3. Use the + # storage helper that already knows how to find the live workspace, + # plus the ``CMIND_WORKSPACE`` env var as a final hint. if not os.path.isdir(os.path.join(workspace_root, ".cmind")): - inferred = args.rpg.resolve().parent.parent.parent - if (inferred / ".cmind").is_dir(): + try: + from cmind_cli._storage import find_workspace_root_from + except Exception: + find_workspace_root_from = None + + inferred: Path | None = None + if find_workspace_root_from is not None: + try: + inferred = find_workspace_root_from(Path.cwd()) + except Exception: + inferred = None + if inferred is None: + env = os.environ.get("CMIND_WORKSPACE") + if env: + cand = Path(env).expanduser() + if cand.is_dir(): + inferred = cand + if inferred is not None and (inferred / ".cmind").is_dir(): workspace_root = str(inferred) os.chdir(workspace_root) diff --git a/CoderMind/src/cmind_cli/__init__.py b/CoderMind/src/cmind_cli/__init__.py index a878457..e7d28a0 100644 --- a/CoderMind/src/cmind_cli/__init__.py +++ b/CoderMind/src/cmind_cli/__init__.py @@ -839,11 +839,19 @@ def _install_source() -> str: _GITIGNORE_CMIND_COMMON = """\ # Runtime workspace (logs, generated data, trajectory) -.cmind/ +# NOTE: ``.cmind/*`` (glob), not ``.cmind/`` (whole-dir). Git does not +# descend into a directory ignored as a whole, so the ``!`` negation +# below would have no effect with the directory form. +.cmind/* # but DO track the workspace AI config so collaborators see the same # default — see docs/configuration.md !.cmind/config.toml +# Legacy runtime dir from pre-cmind (rpgkit) workspaces — kept so users +# upgrading don't accidentally commit stale data while the old directory +# still exists alongside .cmind/. +.rpgkit/ + # Codegen dev environments .venv_dev/ .cmind_dev_env/ diff --git a/CoderMind/templates/commands/build_skeleton.md b/CoderMind/templates/commands/build_skeleton.md index 278619a..9c5c6c3 100644 --- a/CoderMind/templates/commands/build_skeleton.md +++ b/CoderMind/templates/commands/build_skeleton.md @@ -24,7 +24,7 @@ Run the script `cmind script check_skeleton.py` to verify the current state. 1. Inspect the `type` field in the output: - * `error` → Display the error message and stop. Instruct user to run `/cmind.refactor_feature` first. Terminate this command. + * `error` → Display the error message and stop. Instruct user to run `/cmind.feature_refactor` first. Terminate this command. * `init` → Proceed to Step 2. * `warning` → Display the following prompt and wait for user confirmation: diff --git a/CoderMind/utils/build_dep_graph.py b/CoderMind/utils/build_dep_graph.py index 7de5932..6834ca6 100644 --- a/CoderMind/utils/build_dep_graph.py +++ b/CoderMind/utils/build_dep_graph.py @@ -145,6 +145,7 @@ def _filter_build(file_id: str) -> bool: ".venv", "venv", ".idea", ".vscode", ".pytest_cache", ".mypy_cache", "build", "dist", ".cmind", ".venv_dev", + ".rpgkit", # legacy runtime dir (pre-rename), skip if still present } FILE_BL = { "Makefile", "CMakeLists.txt", "Dockerfile", diff --git a/README.md b/README.md index 4a5c898..be111a9 100644 --- a/README.md +++ b/README.md @@ -9,9 +9,6 @@ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -> [!NOTE] -> **CoderMind** is the new name for **RPG-Kit**. The product has been renamed; the install command (`rpgkit`) and package (`rpgkit-cli`) will be renamed in a subsequent release. - 🔥 **New: [CoderMind](CoderMind/) is now open source for Claude Code and GitHub Copilot.** Coding agents often lose repository-level context across long tasks: requirements drift, architecture decisions disappear, and edits miss hidden dependencies. From cf9f5e485fe165dbbc787d3d9a1121b57d2f8228 Mon Sep 17 00:00:00 2001 From: Yasen Hu <74404492+HuYaSen@users.noreply.github.com> Date: Thu, 28 May 2026 19:29:24 +0800 Subject: [PATCH 3/3] fix(cmind): address second-round review (latent rename issues) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pre-release/release scripts: * get-next-version.sh / get-next-pre-version.sh: bridge from rpgkit-v* tags so the first cmind release continues from rpgkit-v0.1.4 cmind_cli/__init__.py: * _maybe_offer_initial_encode: use _storage.workspace_data_dir so the rpg.json existence check matches where the encoder actually writes * Drop _cleanup_legacy_codegen_persistent entirely. The pre-C4 codegen auto-load files lived under /repo/ (a layout retired long before this rename) and were never written under the cmind name. cmind init/update overwriting the slash-command templates is sufficient to refresh user prompts. cmind_cli/_storage.py: * Comment article fix: "an cmind" → "a cmind" --- .../scripts/cmind/get-next-pre-version.sh | 20 +++- .../scripts/cmind/get-next-version.sh | 21 +++- CoderMind/src/cmind_cli/__init__.py | 99 ++----------------- CoderMind/src/cmind_cli/_storage.py | 2 +- 4 files changed, 50 insertions(+), 92 deletions(-) diff --git a/.github/workflows/scripts/cmind/get-next-pre-version.sh b/.github/workflows/scripts/cmind/get-next-pre-version.sh index aa3d272..aa7ae77 100755 --- a/.github/workflows/scripts/cmind/get-next-pre-version.sh +++ b/.github/workflows/scripts/cmind/get-next-pre-version.sh @@ -8,6 +8,9 @@ fi RUN_NUMBER="$1" TAG_PREFIX="${TAG_PREFIX:-cmind-v}" +# Legacy tag prefix (pre-rename) — used as a base when no cmind-v* tag +# exists yet, so pre-releases do not regress versions. +LEGACY_TAG_PREFIX="${LEGACY_TAG_PREFIX:-rpgkit-v}" INITIAL_VERSION="${INITIAL_VERSION:-0.1.0}" write_output() { @@ -18,11 +21,26 @@ LATEST_TAG=$(git tag -l "${TAG_PREFIX}[0-9]*.[0-9]*.[0-9]*" --sort=-v:refname \ | grep -E "^${TAG_PREFIX}[0-9]+\.[0-9]+\.[0-9]+$" \ | head -n1 || true) +# Bridge across the rpgkit → cmind rename: when there is no cmind-v* +# tag yet, derive the version base from the most recent rpgkit-v* tag +# so pre-releases continue from the existing version line. The *new* +# tag still uses TAG_PREFIX (cmind-v). +LEGACY_PREFIX_USED="$TAG_PREFIX" +if [[ -z "$LATEST_TAG" ]]; then + LEGACY_LATEST=$(git tag -l "${LEGACY_TAG_PREFIX}[0-9]*.[0-9]*.[0-9]*" --sort=-v:refname \ + | grep -E "^${LEGACY_TAG_PREFIX}[0-9]+\.[0-9]+\.[0-9]+$" \ + | head -n1 || true) + if [[ -n "$LEGACY_LATEST" ]]; then + LATEST_TAG="$LEGACY_LATEST" + LEGACY_PREFIX_USED="$LEGACY_TAG_PREFIX" + fi +fi + if [[ -z "$LATEST_TAG" ]]; then LATEST_TAG="${TAG_PREFIX}0.0.0" BASE_VERSION="$INITIAL_VERSION" else - BASE_VERSION="${LATEST_TAG#${TAG_PREFIX}}" + BASE_VERSION="${LATEST_TAG#${LEGACY_PREFIX_USED}}" fi write_output "latest_tag=$LATEST_TAG" diff --git a/.github/workflows/scripts/cmind/get-next-version.sh b/.github/workflows/scripts/cmind/get-next-version.sh index 6840061..0a4818a 100755 --- a/.github/workflows/scripts/cmind/get-next-version.sh +++ b/.github/workflows/scripts/cmind/get-next-version.sh @@ -2,6 +2,10 @@ set -euo pipefail TAG_PREFIX="${TAG_PREFIX:-cmind-v}" +# Legacy tag prefix (pre-rename) — considered as a fallback so the +# first cmind-v* release continues the existing version line instead of +# resetting to INITIAL_VERSION (which would be a downgrade). +LEGACY_TAG_PREFIX="${LEGACY_TAG_PREFIX:-rpgkit-v}" write_output() { [[ -n "${GITHUB_OUTPUT:-}" ]] && echo "$1" >> "$GITHUB_OUTPUT" @@ -13,11 +17,26 @@ LATEST_TAG=$(git tag -l "${TAG_PREFIX}[0-9]*.[0-9]*.[0-9]*" --sort=-v:refname \ | grep -E "^${TAG_PREFIX}[0-9]+\.[0-9]+\.[0-9]+$" \ | head -n1 || true) +# Bridge across the rpgkit → cmind rename: when there is no cmind-v* tag +# yet, derive the version number from the most recent rpgkit-v* tag so +# the first cmind-v* release continues the existing version line. The +# *new* tag still uses TAG_PREFIX (cmind-v). +LEGACY_PREFIX_USED="$TAG_PREFIX" +if [[ -z "$LATEST_TAG" ]]; then + LEGACY_LATEST=$(git tag -l "${LEGACY_TAG_PREFIX}[0-9]*.[0-9]*.[0-9]*" --sort=-v:refname \ + | grep -E "^${LEGACY_TAG_PREFIX}[0-9]+\.[0-9]+\.[0-9]+$" \ + | head -n1 || true) + if [[ -n "$LEGACY_LATEST" ]]; then + LATEST_TAG="$LEGACY_LATEST" + LEGACY_PREFIX_USED="$LEGACY_TAG_PREFIX" + fi +fi + if [[ -z "$LATEST_TAG" ]]; then LATEST_TAG="${TAG_PREFIX}0.0.0" NEW_VERSION="v$INITIAL_VERSION" else - VERSION="${LATEST_TAG#${TAG_PREFIX}}" + VERSION="${LATEST_TAG#${LEGACY_PREFIX_USED}}" IFS='.' read -ra VERSION_PARTS <<< "$VERSION" MAJOR=${VERSION_PARTS[0]:-0} MINOR=${VERSION_PARTS[1]:-0} diff --git a/CoderMind/src/cmind_cli/__init__.py b/CoderMind/src/cmind_cli/__init__.py index e7d28a0..ce79ac0 100644 --- a/CoderMind/src/cmind_cli/__init__.py +++ b/CoderMind/src/cmind_cli/__init__.py @@ -1506,61 +1506,6 @@ def _cleanup_legacy_vscode_mcp(project_path: Path) -> None: pass -def _cleanup_legacy_codegen_persistent(project_path: Path) -> list[str]: - """Delete obsolete ``cmind-codegen.*`` persistent-instruction files. - - Earlier versions of ``cmind init`` (pre-C4 cleanup) wrote a - codegen-specific instructions file that AI agents would auto-load on - every session, polluting unrelated commands (rpg_edit, encode, plain - Q&A) with codegen workflow noise. - - This helper: - - * Removes ``/.claude/rules/cmind-codegen.md`` - * Removes ``/.github/instructions/cmind-codegen.instructions.md`` - * Also cleans the legacy ``/repo/.claude/...`` and - ``/repo/.github/...`` paths, so workspaces created - under the old ``/repo`` layout are upgraded on the - next ``cmind init`` / ``cmind update`` run. - * Tidies up empty parent directories the file leaves behind. - * Returns the list of paths actually removed (for tracker reporting). - - The function is safe to call repeatedly and on workspaces that never - had the legacy file. - """ - legacy_repo_dir = project_path / "repo" - candidates = [ - # New layout (workspace == repo) - project_path / ".claude" / "rules" / "cmind-codegen.md", - project_path / ".github" / "instructions" / "cmind-codegen.instructions.md", - # Legacy layout (/repo) — keep scanning so users who - # upgrade from old workspaces still get the file removed. - legacy_repo_dir / ".claude" / "rules" / "cmind-codegen.md", - legacy_repo_dir / ".github" / "instructions" / "cmind-codegen.instructions.md", - ] - - removed: list[str] = [] - for path in candidates: - if not path.is_file(): - continue - try: - path.unlink() - removed.append(str(path.relative_to(project_path))) - except OSError: - continue - - # Tidy up empty parent dirs (only if the parent contains nothing - # else; we never delete user-owned content). - parent = path.parent - try: - if parent.exists() and not any(parent.iterdir()): - parent.rmdir() - except OSError: - pass - - return removed - - def _generate_mcp_config( project_path: Path, selected_ai: str, @@ -2284,8 +2229,16 @@ def _maybe_offer_initial_encode( Failures never propagate — ``cmind init`` is already done and we don't want a flaky encoder to taint the exit code. """ - # Already encoded: nothing to do. - rpg_file = project_path / ".cmind" / "data" / "rpg.json" + # Already encoded: nothing to do. rpg.json lives in the home-side + # workspace store (``~/.cmind/workspaces//data/rpg.json``), not + # in the workspace-local ``.cmind/data/`` — use the storage helper + # so this check matches where the encoder actually writes. + try: + rpg_file = _storage.workspace_data_dir(project_path) / "rpg.json" + except Exception: + # Fallback for environments where storage resolution fails; + # err on the side of running the encoder rather than skipping it. + rpg_file = project_path / ".cmind" / "data" / "rpg.json" if rpg_file.exists(): return @@ -3951,7 +3904,6 @@ def init( ("gitignore", "Configure .gitignore"), ("mcp", "Configure MCP server"), ("copilot-cli-mcp", "Register rpg-tools in ~/.copilot/mcp-config.json"), - ("legacy-cleanup", "Remove obsolete persistent rules"), ("cleanup", "Cleanup"), ("git", "Initialize git repository"), ("hooks", "Install auto-update hooks"), @@ -4016,21 +3968,6 @@ def init( tracker.start("copilot-cli-mcp") _register_copilot_cli_global_mcp(tracker=tracker) - # Migrate workspaces created before C4: drop the auto-loaded - # cmind-codegen.* persistent-instruction files. - tracker.start("legacy-cleanup") - try: - removed = _cleanup_legacy_codegen_persistent(project_path) - if removed: - tracker.complete( - "legacy-cleanup", - f"removed {len(removed)} file(s)", - ) - else: - tracker.skip("legacy-cleanup", "none") - except Exception as exc: - tracker.error("legacy-cleanup", str(exc)) - if not no_git: tracker.start("git") if is_git_repo(project_path): @@ -4552,7 +4489,6 @@ def update( ("gitignore", "Configure .gitignore"), ("mcp", "Configure MCP server"), ("copilot-cli-mcp", "Register rpg-tools in ~/.copilot/mcp-config.json"), - ("legacy-cleanup", "Remove obsolete persistent rules"), ("hooks", "Install auto-update hooks"), ("cleanup", "Cleanup"), ("final", "Finalize"), @@ -4615,21 +4551,6 @@ def update( tracker.start("copilot-cli-mcp") _register_copilot_cli_global_mcp(tracker=tracker) - # Migrate workspaces created before C4: drop the auto-loaded - # cmind-codegen.* persistent-instruction files. - tracker.start("legacy-cleanup") - try: - removed = _cleanup_legacy_codegen_persistent(project_path) - if removed: - tracker.complete( - "legacy-cleanup", - f"removed {len(removed)} file(s)", - ) - else: - tracker.skip("legacy-cleanup", "none") - except Exception as exc: - tracker.error("legacy-cleanup", str(exc)) - # Re-install hooks so behavior fixes propagate to existing # workspaces. Without this, the .git/hooks/* files stay # frozen at whatever version was active during the original diff --git a/CoderMind/src/cmind_cli/_storage.py b/CoderMind/src/cmind_cli/_storage.py index bc5fcc9..d029114 100644 --- a/CoderMind/src/cmind_cli/_storage.py +++ b/CoderMind/src/cmind_cli/_storage.py @@ -101,7 +101,7 @@ #: Subdirectory of the user's home where cmind keeps all per-workspace data. HOME_ROOT_RELPATH = Path(".cmind") / "workspaces" -#: Marker file inside the workspace that identifies it as an cmind +#: Marker file inside the workspace that identifies it as a cmind #: workspace. ``cmind init`` writes this; cwd-walk-up looks for it. WORKSPACE_MARKER_RELPATH = Path(".cmind") / "config.toml"