@rtorcato/repo-tooling 3.8.6 → 3.8.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/base/checks.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
|
+
import { BLOCK_START, hasStaleAgentBlock } from '../cli/generators/agent-rules.js';
|
|
3
4
|
import { BADGE_START, hasPublicOnlyBadges } from '../cli/generators/badges.js';
|
|
4
5
|
import { detectNestedLanguages } from '../cli/utils/detect-language.js';
|
|
5
6
|
/**
|
|
@@ -335,19 +336,37 @@ export async function checkCoverageUpload(dir) {
|
|
|
335
336
|
};
|
|
336
337
|
}
|
|
337
338
|
export async function checkAiSetup(dir) {
|
|
338
|
-
// Consider AI setup present if
|
|
339
|
-
// Claude skill is installed — the
|
|
340
|
-
|
|
341
|
-
const
|
|
342
|
-
|
|
339
|
+
// Consider AI setup present if one of the block-managed files carries the
|
|
340
|
+
// agent block or the Claude skill is installed — the markers `fix ai` writes.
|
|
341
|
+
let blockFile = null;
|
|
342
|
+
const stale = [];
|
|
343
|
+
for (const rel of ['AGENTS.md', 'CLAUDE.md', path.join('.github', 'copilot-instructions.md')]) {
|
|
344
|
+
const filepath = path.join(dir, rel);
|
|
345
|
+
if (!(await fs.pathExists(filepath)))
|
|
346
|
+
continue;
|
|
347
|
+
const content = await fs.readFile(filepath, 'utf8');
|
|
348
|
+
if (!content.includes(BLOCK_START))
|
|
349
|
+
continue;
|
|
350
|
+
blockFile ??= rel;
|
|
351
|
+
if (hasStaleAgentBlock(content))
|
|
352
|
+
stale.push(rel);
|
|
353
|
+
}
|
|
343
354
|
const hasSkill = (await fs.pathExists(path.join(dir, '.claude', 'skills', 'repo-tooling.md'))) ||
|
|
344
355
|
// Pre-rename name — still counts as present until `fix` migrates it.
|
|
345
356
|
(await fs.pathExists(path.join(dir, '.claude', 'skills', 'js-tooling.md')));
|
|
346
|
-
if (
|
|
357
|
+
if (stale.length > 0) {
|
|
358
|
+
return {
|
|
359
|
+
check: 'AI setup',
|
|
360
|
+
status: 'drift',
|
|
361
|
+
detail: `${stale.join(', ')} still point agents at the dead \`js-tooling\` package/bin`,
|
|
362
|
+
hint: 'Run `npx @rtorcato/repo-tooling fix ai` to refresh the agent instructions in place',
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
if (blockFile || hasSkill) {
|
|
347
366
|
return {
|
|
348
367
|
check: 'AI setup',
|
|
349
368
|
status: 'ok',
|
|
350
|
-
detail:
|
|
369
|
+
detail: blockFile ? `${blockFile} has the agent block` : '.claude skill installed',
|
|
351
370
|
};
|
|
352
371
|
}
|
|
353
372
|
return {
|
|
@@ -352,6 +352,14 @@ const PROTECTION_BODY = JSON.stringify({
|
|
|
352
352
|
// enforce_admins off so the App/RELEASE_TOKEN can bypass to push release commits.
|
|
353
353
|
enforce_admins: false,
|
|
354
354
|
// Required human review would deadlock solo Dependabot auto-merge.
|
|
355
|
+
//
|
|
356
|
+
// Note this is *applied*, not merely tolerated: checkBranchProtection reports
|
|
357
|
+
// any required_pull_request_reviews as drift, so `fix github-settings` PUTs it
|
|
358
|
+
// back to null. A repo that deliberately requires approvals will have that
|
|
359
|
+
// silently reverted by the next unrelated fix run, with nothing in the output
|
|
360
|
+
// naming the rule that was removed. Known downstream case: the ai-issue-loop
|
|
361
|
+
// pipeline works around it with approval labels precisely because of this.
|
|
362
|
+
// Loosen the standard here first if a repo ever genuinely needs review gating.
|
|
355
363
|
required_pull_request_reviews: null,
|
|
356
364
|
restrictions: null,
|
|
357
365
|
allow_force_pushes: false,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import { copyPreset, getPackageRoot } from '../utils/copy-preset.js';
|
|
4
|
+
import { LEGACY_TOOL_NAME } from '../utils/lockfile.js';
|
|
4
5
|
import { installSkillsInstallDocs } from './skills-install.js';
|
|
5
6
|
/**
|
|
6
7
|
* All agent rule files are generated from one source of truth — the shipped
|
|
@@ -8,8 +9,25 @@ import { installSkillsInstallDocs } from './skills-install.js';
|
|
|
8
9
|
* location and the frontmatter differ per agent.
|
|
9
10
|
*/
|
|
10
11
|
const SOURCE = 'tooling/claude/repo-tooling.md';
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
// The markers keep the pre-rename text on purpose: changing them would orphan
|
|
13
|
+
// every block already written and append a second one on the next fix.
|
|
14
|
+
export const BLOCK_START = '<!-- js-tooling:start -->';
|
|
15
|
+
export const BLOCK_END = '<!-- js-tooling:end -->';
|
|
16
|
+
/**
|
|
17
|
+
* True when a managed block still names the pre-rename package or bin — a repo
|
|
18
|
+
* scaffolded before the rename tells agents to run `js-tooling fix ai`, which
|
|
19
|
+
* is not a runnable command (#393). Only the block *body* is inspected: the
|
|
20
|
+
* markers carry the legacy name by design, so matching on the whole file would
|
|
21
|
+
* report every repo as permanently stale.
|
|
22
|
+
*/
|
|
23
|
+
export function hasStaleAgentBlock(content) {
|
|
24
|
+
const start = content.indexOf(BLOCK_START);
|
|
25
|
+
if (start === -1)
|
|
26
|
+
return false;
|
|
27
|
+
const bodyStart = start + BLOCK_START.length;
|
|
28
|
+
const end = content.indexOf(BLOCK_END, bodyStart);
|
|
29
|
+
return content.slice(bodyStart, end === -1 ? undefined : end).includes(LEGACY_TOOL_NAME);
|
|
30
|
+
}
|
|
13
31
|
/** Read the shipped skill and split its frontmatter from the markdown body. */
|
|
14
32
|
async function readSkill() {
|
|
15
33
|
const raw = await fs.readFile(path.join(getPackageRoot(), SOURCE), 'utf8');
|
|
@@ -3,10 +3,14 @@ import fs from 'fs-extra';
|
|
|
3
3
|
import packageJson from '../../../package.json' with { type: 'json' };
|
|
4
4
|
import { validateProjectConfig } from '../commands/setup-presets.js';
|
|
5
5
|
export const LOCKFILE_NAME = '.repo-tooling.json';
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
export const
|
|
6
|
+
// Package and bin name used before the js-tooling→repo-tooling rename (#272).
|
|
7
|
+
// The bin no longer exists and the package is 404 on the registry, so any
|
|
8
|
+
// generated file still naming it is stale (#393).
|
|
9
|
+
export const LEGACY_TOOL_NAME = 'js-tooling';
|
|
10
|
+
// Lockfile name from the same era. Repos set up on an older version still have
|
|
11
|
+
// it: readLockfile falls back to it, and writeLockfile migrates to the new name
|
|
12
|
+
// (removing the old file) on the next write.
|
|
13
|
+
export const LEGACY_LOCKFILE_NAME = `.${LEGACY_TOOL_NAME}.json`;
|
|
10
14
|
// v2 added ProjectConfig.language (multi-language seam, #140). v1 files are
|
|
11
15
|
// migrated to v2 on read, defaulting language to 'js'.
|
|
12
16
|
export const LOCKFILE_VERSION = 2;
|
package/package.json
CHANGED