Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import eslintConfigPrettier from 'eslint-config-prettier';

export default [
{
ignores: ['node_modules/', 'dist/', 'coverage/', '*.min.js', 'templates/'],
ignores: ['node_modules/', 'dist/', 'coverage/', '.context/', '*.min.js', 'templates/'],
},
js.configs.recommended,
eslintConfigPrettier,
Expand Down
2 changes: 2 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module.exports = {
testEnvironment: 'node',
testMatch: ['**/test/**/*.test.js', '**/test/**/*.spec.js'],
testPathIgnorePatterns: ['<rootDir>/.context/worktrees/'],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Ignore every .context artifact in Jest

Because this only excludes .context/worktrees, Jest's testMatch still discovers tests in other .context subdirectories. In this repo, agents are instructed to store intermediate artifacts under .context/, and I verified npx --no-install jest --config jest.config.js --runInBand --reporters=default --listTests lists .context/review-jest/test/leak.test.js; such artifacts can make npm test fail despite the quality-gate fix. Consider ignoring <rootDir>/.context/ rather than only worktrees.

Useful? React with 👍 / 👎.

modulePathIgnorePatterns: ['<rootDir>/.context/worktrees/'],
collectCoverageFrom: [
'**/*.{js,mjs,cjs}',
'!script/**/*',
Expand Down
15 changes: 14 additions & 1 deletion script/update-agents-md.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,17 @@ workflow_files() {
find .github/workflows -maxdepth 1 -type f \( -name '*.yml' -o -name '*.yaml' \) | sort
}

dir_has_tracked_files() {
local dir="$1"

if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
[[ -n "$(git ls-files -- "$dir/" | head -n 1)" ]]
return
fi

[[ -n "$(find "$dir" -type f -print -quit)" ]]
}

# shellcheck disable=SC2034 # NODE_VER / PM consumed by template via eval
NODE_VER=$(jq -r '.engines.node // empty' package.json 2>/dev/null)
# shellcheck disable=SC2034
Expand All @@ -72,10 +83,11 @@ collect_dirs() {
[[ "$d" == "./" || "$d" == "../" ]] && continue
name="${d%/}"
[[ "$name" == .git || "$name" == .git-* ]] && continue
dir_has_tracked_files "$name" || continue

if [[ "$name" == ".claude" ]]; then
for sub in "${CLAUDE_SUB_ORDER[@]}"; do
[[ -d ".claude/$sub" ]] && emit out "\`.claude/$sub/\`" "${CLAUDE_SUB_PURPOSE[$sub]}"
[[ -d ".claude/$sub" ]] && dir_has_tracked_files ".claude/$sub" && emit out "\`.claude/$sub/\`" "${CLAUDE_SUB_PURPOSE[$sub]}"
done
continue
fi
Expand All @@ -90,6 +102,7 @@ collect_dirs() {
for d in */; do
name="${d%/}"
[[ "$REG_DIR_SKIP" == *" $name "* ]] && continue
dir_has_tracked_files "$name" || continue
purpose="${REG_DIR_PURPOSE[$name]:-$name}"
emit out "\`$name/\`" "$purpose"
done
Expand Down
40 changes: 40 additions & 0 deletions test/claude-workflow-contract.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,39 @@ function runRequiredWorkflowScript(workflows) {
}
}

function runUpdateAgentsScriptWithUntrackedDirectory() {
const contextDir = path.join(repoPath, '.context');
fs.mkdirSync(contextDir, { recursive: true });
const tempRoot = fs.mkdtempSync(path.join(contextDir, 'agents-md-test-'));

try {
fs.writeFileSync(
path.join(tempRoot, 'AGENTS.md'),
['# Test Agents', '', '<!-- BEGIN AUTO-GENERATED -->', '<!-- END AUTO-GENERATED -->', ''].join('\n'),
);
fs.writeFileSync(
path.join(tempRoot, 'package.json'),
JSON.stringify({ scripts: {}, engines: { node: '24.14.1' } }, null, 2),
);
fs.mkdirSync(path.join(tempRoot, 'docs'), { recursive: true });
fs.writeFileSync(path.join(tempRoot, 'docs', 'README.md'), '# Docs\n');
fs.mkdirSync(path.join(tempRoot, 'next'), { recursive: true });

execFileSync('git', ['init'], { cwd: tempRoot, stdio: 'ignore' });
execFileSync('git', ['add', 'AGENTS.md', 'package.json', 'docs/README.md'], {
cwd: tempRoot,
stdio: 'ignore',
});

const scriptPath = path.join(repoPath, 'script', 'update-agents-md.sh');
execFileSync('bash', [scriptPath], { cwd: tempRoot, encoding: 'utf8' });

return fs.readFileSync(path.join(tempRoot, 'AGENTS.md'), 'utf8');
} finally {
fs.rmSync(tempRoot, { recursive: true, force: true });
}
}

describe('Claude workflow contracts', () => {
const issueWorkflows = ['.github/workflows/claude.yml', 'templates/workflows/claude.yml'];
const maintenanceWorkflows = [
Expand Down Expand Up @@ -230,6 +263,13 @@ describe('Claude workflow contracts', () => {
expect(script).not.toContain('mktemp -d -t agents-md-check');
});

test('update-agents-md ignores untracked project directories', () => {
const generated = runUpdateAgentsScriptWithUntrackedDirectory();

expect(generated).toContain('`docs/`');
expect(generated).not.toContain('`next/`');
});

test('repo-maintenance scans yml and yaml workflows in cross-workflow checks', () => {
const script = readWorkflow('script/repo-maintenance.sh');

Expand Down
8 changes: 7 additions & 1 deletion test/eslint-config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function makeTempDir(prefix) {
}

function runEslint(filePath, extraArgs = []) {
return execFileSync(eslintBin, ['--config', configPath, ...extraArgs, filePath], {
return execFileSync(eslintBin, ['--config', configPath, '--no-ignore', ...extraArgs, filePath], {
cwd: repoPath,
encoding: 'utf8',
stdio: ['ignore', 'pipe', 'pipe'],
Expand All @@ -33,6 +33,12 @@ function expectEslintFailure(filePath, extraArgs = []) {
}

describe('ESLint configuration runtime behavior', () => {
test('ignores shared context artifacts during full repository lint', () => {
const config = fs.readFileSync(configPath, 'utf8');

expect(config).toContain("'.context/'");
});

test('allows console usage and ignored underscore arguments', () => {
const tempDir = makeTempDir('eslint-valid');
try {
Expand Down
2 changes: 1 addition & 1 deletion test/integration/audit_references.bats
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ assert_tsv_row() {
run "$REPO_ROOT/script/audit-references.sh" --format tsv
assert_success

assert_tsv_row docs script/audit-references.sh .context/refactoring-baseline.md
assert_tsv_row docs script/README.md docs/README.md
assert_tsv_row test script/audit-references.sh test/integration/core-scripts.bats
assert_tsv_row code/ci templates/workflows/claude.yml templates/workflows/claude-health-check.yml
assert_tsv_row test templates/workflows/claude-health-check.yml test/template-workflows.test.js
Expand Down
5 changes: 5 additions & 0 deletions test/jest-config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ function expectJestFailure(args) {
}

describe('Jest configuration runtime behavior', () => {
test('ignores persistent worktrees under .context', () => {
expect(baseJestConfig.testPathIgnorePatterns).toContain('<rootDir>/.context/worktrees/');
expect(baseJestConfig.modulePathIgnorePatterns).toContain('<rootDir>/.context/worktrees/');
});

test('runs a matching test file in the Node environment', () => {
const tempDir = makeTempDir('jest-runtime');
try {
Expand Down
Loading