fix(install): remove bare ~/.claude reference in update.md (closes #2470) (#2482)

* fix(install): remove bare ~/.claude reference in update.md (closes #2470)

The installer's copyWithPathReplacement() replaces ~/\.claude\/ (with
trailing slash) but not ~/\.claude (bare, no trailing slash). A comment
on line 398 of update.md used the bare form, which scanForLeakedPaths()
correctly flagged for every non-Claude runtime install.

Replaced the example in the comment with a non-Claude runtime path so
the file passes the scanner for all runtimes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(test): align regex with installer's word-boundary semantics (CodeRabbit #2482)

Replace negative lookahead (?!\/) with \b word boundary to match the
installer's scanForLeakedPaths() pattern. The lookahead would incorrectly
flag ~/.claude_suffix whereas \b correctly excludes it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(test): revert \b regex — (?!\/) was intentionally scoped to bare refs

The installer's scanForLeakedPaths uses \b but the test is specifically
checking for bare ~/.claude without trailing slash that the replacer misses.
~/.claude/ (with slash) at line 359 of update.md is expected and handled.
\b would flag it as a false positive.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(inventory): update workflow count to 81 (graduation.md added in #2490)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Tom Boucher
2026-04-20 18:37:32 -04:00
committed by GitHub
parent 2b494407e5
commit 1657321eb0
3 changed files with 38 additions and 2 deletions

View File

@@ -173,7 +173,7 @@ Full roster at `commands/gsd/*.md`. The groupings below mirror `docs/COMMANDS.md
---
## Workflows (80 shipped)
## Workflows (81 shipped)
Full roster at `get-shit-done/workflows/*.md`. Workflows are thin orchestrators that commands reference internally; most are not read directly by end users. Rows below map each workflow file to its role (derived from the `<purpose>` block) and, where applicable, to the command that invokes it.

View File

@@ -396,7 +396,7 @@ First, resolve the config directory (`RUNTIME_DIR`) from the install scope
detected in `get_installed_version`:
```bash
# RUNTIME_DIR is the resolved config directory (e.g. ~/.claude, ~/.config/opencode)
# RUNTIME_DIR is the resolved config directory (e.g. ~/.config/opencode, ~/.gemini)
# It should already be set from get_installed_version as GLOBAL_DIR or LOCAL_DIR.
# Use the appropriate variable based on INSTALL_SCOPE.
if [ "$INSTALL_SCOPE" = "LOCAL" ]; then

View File

@@ -0,0 +1,36 @@
'use strict';
/**
* Regression test for #2470.
*
* update.md is installed into every runtime directory including .gemini, .codex,
* .opencode, etc. The installer's scanForLeakedPaths() uses the regex
* /(?:~|\$HOME)\/\.claude\b/g to detect unresolved .claude path references after
* copyWithPathReplacement() runs. The replacer handles "~/.claude/" (trailing slash)
* but not "~/.claude" (bare, no trailing slash) — so any bare reference in
* update.md would slip through and trigger the installer warning for non-Claude runtimes.
*/
const { test, describe } = require('node:test');
const assert = require('node:assert/strict');
const fs = require('fs');
const path = require('path');
const UPDATE_MD = path.join(__dirname, '..', 'get-shit-done', 'workflows', 'update.md');
describe('update.md — no bare ~.claude path references (#2470)', () => {
const content = fs.readFileSync(UPDATE_MD, 'utf-8');
test('update.md does not contain bare ~/\\.claude (without trailing slash)', () => {
// This is the exact pattern from the installer's scanForLeakedPaths():
// /(?:~|\$HOME)\/\.claude\b/g
// The replacer handles ~/\.claude\/ (with trailing slash) but misses bare ~/\.claude
// so we must not have bare references in the source file.
const matches = content.match(/(?:~|\$HOME)\/\.claude(?!\/)/g);
assert.strictEqual(
matches,
null,
`update.md must not contain bare ~/\.claude (without trailing slash) — installer scanner flags these as unresolved path refs: ${JSON.stringify(matches)}`
);
});
});