gitnexus 1.6.10-rc.22 → 1.6.10-rc.24
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/README.md +2 -2
- package/dist/cli/ai-context.js +23 -13
- package/dist/cli/analyze.d.ts +1 -1
- package/dist/cli/i18n/en.d.ts +1 -1
- package/dist/cli/i18n/en.js +1 -1
- package/dist/cli/i18n/resources.d.ts +1 -1
- package/dist/cli/i18n/zh-CN.js +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/skill-gen.js +38 -18
- package/dist/core/run-analyze.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -233,7 +233,7 @@ gitnexus analyze --embeddings # Enable embedding generation (slower, better s
|
|
|
233
233
|
gitnexus embeddings install # Fetch the optional local embedding stack on demand (--cuda, --force)
|
|
234
234
|
gitnexus analyze --skills # Generate repo-specific skill files from detected communities
|
|
235
235
|
gitnexus analyze --skip-agents-md # Preserve custom AGENTS.md/CLAUDE.md gitnexus section edits
|
|
236
|
-
gitnexus analyze --skip-skills # Skip installing .claude/skills/gitnexus
|
|
236
|
+
gitnexus analyze --skip-skills # Skip installing standard .claude/skills/gitnexus-* skill files
|
|
237
237
|
gitnexus analyze --skip-git # Index folders that are not Git repositories
|
|
238
238
|
gitnexus analyze --workers <n> # Parse worker pool size (>=1; default: cores-1, capped at 16)
|
|
239
239
|
gitnexus analyze --verbose # Log skipped files when parsers are unavailable
|
|
@@ -328,7 +328,7 @@ GitNexus ships with skill files that teach AI agents how to use the tools effect
|
|
|
328
328
|
- **Guide** — GitNexus tool/resource/schema reference for the agent
|
|
329
329
|
- **CLI** — Run analyze/status/clean/wiki commands on request
|
|
330
330
|
|
|
331
|
-
Installed automatically by both `gitnexus analyze` (per-repo) and `gitnexus setup` (global). Run `gitnexus analyze --skills` to additionally generate
|
|
331
|
+
Installed automatically by both `gitnexus analyze` (per-repo) and `gitnexus setup` (global). Run `gitnexus analyze --skills` to additionally generate each detected functional area as a direct project skill under `.claude/skills/gitnexus-area-<name>/`.
|
|
332
332
|
|
|
333
333
|
## Requirements
|
|
334
334
|
|
package/dist/cli/ai-context.js
CHANGED
|
@@ -81,22 +81,22 @@ export function generateGitNexusContent(projectName, stats, opts = {}) {
|
|
|
81
81
|
const { generatedSkills, groupNames, noStats, skipSkills, runnerPath = '.gitnexus/run.cjs', defaultBranch = 'main', hasPdg = false, } = opts;
|
|
82
82
|
const generatedRows = generatedSkills && generatedSkills.length > 0
|
|
83
83
|
? generatedSkills
|
|
84
|
-
.map((s) => `| Work in the ${s.label} area (${s.symbolCount} symbols) | \`.claude/skills
|
|
84
|
+
.map((s) => `| Work in the ${s.label} area (${s.symbolCount} symbols) | \`.claude/skills/${s.name}/SKILL.md\` |`)
|
|
85
85
|
.join('\n')
|
|
86
86
|
: '';
|
|
87
87
|
// Standard skill rows reference files installed by installSkills(). When
|
|
88
88
|
// --skip-skills suppresses that install, these rows must be omitted — else
|
|
89
89
|
// AGENTS.md/CLAUDE.md would direct agents to read files that don't exist.
|
|
90
|
-
// Community skills (generatedRows) live
|
|
90
|
+
// Community skills (generatedRows) live directly under .claude/skills/ and
|
|
91
91
|
// are independent of --skip-skills, so they remain when present.
|
|
92
92
|
const standardSkillsRows = skipSkills
|
|
93
93
|
? ''
|
|
94
|
-
: `| Understand architecture / "How does X work?" | \`.claude/skills/gitnexus
|
|
95
|
-
| Blast radius / "What breaks if I change X?" | \`.claude/skills/gitnexus
|
|
96
|
-
| Trace bugs / "Why is X failing?" | \`.claude/skills/gitnexus
|
|
97
|
-
| Rename / extract / split / refactor | \`.claude/skills/gitnexus
|
|
98
|
-
| Tools, resources, schema reference | \`.claude/skills/gitnexus
|
|
99
|
-
| Index, status, clean, wiki CLI commands | \`.claude/skills/gitnexus
|
|
94
|
+
: `| Understand architecture / "How does X work?" | \`.claude/skills/gitnexus-exploring/SKILL.md\` |
|
|
95
|
+
| Blast radius / "What breaks if I change X?" | \`.claude/skills/gitnexus-impact-analysis/SKILL.md\` |
|
|
96
|
+
| Trace bugs / "Why is X failing?" | \`.claude/skills/gitnexus-debugging/SKILL.md\` |
|
|
97
|
+
| Rename / extract / split / refactor | \`.claude/skills/gitnexus-refactoring/SKILL.md\` |
|
|
98
|
+
| Tools, resources, schema reference | \`.claude/skills/gitnexus-guide/SKILL.md\` |
|
|
99
|
+
| Index, status, clean, wiki CLI commands | \`.claude/skills/gitnexus-cli/SKILL.md\` |`;
|
|
100
100
|
const tableBody = [standardSkillsRows, generatedRows].filter(Boolean).join('\n');
|
|
101
101
|
const skillsTable = tableBody
|
|
102
102
|
? `| Task | Read this skill file |
|
|
@@ -253,11 +253,12 @@ async function upsertGitNexusSection(filePath, content, projectName, stats, noSt
|
|
|
253
253
|
return 'appended';
|
|
254
254
|
}
|
|
255
255
|
/**
|
|
256
|
-
* Install GitNexus skills
|
|
256
|
+
* Install GitNexus skills as direct children of .claude/skills/
|
|
257
257
|
* Works natively with Claude Code, Cursor, and GitHub Copilot
|
|
258
258
|
*/
|
|
259
259
|
async function installSkills(repoPath) {
|
|
260
|
-
const skillsDir = path.join(repoPath, '.claude', 'skills'
|
|
260
|
+
const skillsDir = path.join(repoPath, '.claude', 'skills');
|
|
261
|
+
const legacySkillsDir = path.join(skillsDir, 'gitnexus');
|
|
261
262
|
const installedSkills = [];
|
|
262
263
|
// Skill definitions bundled with the package
|
|
263
264
|
const skills = [
|
|
@@ -314,6 +315,15 @@ Use GitNexus tools to accomplish this task.
|
|
|
314
315
|
}
|
|
315
316
|
await fs.writeFile(skillPath, skillContent, 'utf-8');
|
|
316
317
|
installedSkills.push(skill.name);
|
|
318
|
+
// Previous releases installed these known standard skills one level too
|
|
319
|
+
// deep. Remove only the child owned by this installer; unknown siblings
|
|
320
|
+
// under the legacy grouping directory may be user-authored and survive.
|
|
321
|
+
try {
|
|
322
|
+
await fs.rm(path.join(legacySkillsDir, skill.name), { recursive: true, force: true });
|
|
323
|
+
}
|
|
324
|
+
catch (err) {
|
|
325
|
+
logger.warn({ err }, `Warning: Could not remove legacy skill ${skill.name}:`);
|
|
326
|
+
}
|
|
317
327
|
}
|
|
318
328
|
catch (err) {
|
|
319
329
|
// Skip on error, don't fail the whole process
|
|
@@ -366,15 +376,15 @@ export async function generateAIContextFiles(repoPath, storagePath, projectName,
|
|
|
366
376
|
createdFiles.push('AGENTS.md (skipped via --skip-agents-md)');
|
|
367
377
|
createdFiles.push('CLAUDE.md (skipped via --skip-agents-md)');
|
|
368
378
|
}
|
|
369
|
-
// Install skills
|
|
379
|
+
// Install standard skills directly under .claude/skills/ (unless --skip-skills)
|
|
370
380
|
if (!options?.skipSkills) {
|
|
371
381
|
const installedSkills = await installSkills(repoPath);
|
|
372
382
|
if (installedSkills.length > 0) {
|
|
373
|
-
createdFiles.push(`.claude/skills/gitnexus
|
|
383
|
+
createdFiles.push(`.claude/skills/gitnexus-*/ (${installedSkills.length} skills)`);
|
|
374
384
|
}
|
|
375
385
|
}
|
|
376
386
|
else {
|
|
377
|
-
createdFiles.push('.claude/skills/gitnexus
|
|
387
|
+
createdFiles.push('.claude/skills/gitnexus-*/ (skipped via --skip-skills)');
|
|
378
388
|
}
|
|
379
389
|
return { files: createdFiles };
|
|
380
390
|
}
|
package/dist/cli/analyze.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ export interface AnalyzeOptions {
|
|
|
55
55
|
* default-on case.
|
|
56
56
|
*/
|
|
57
57
|
stats?: boolean;
|
|
58
|
-
/** Skip installing standard GitNexus skill files
|
|
58
|
+
/** Skip installing standard GitNexus skill files directly under .claude/skills/. */
|
|
59
59
|
skipSkills?: boolean;
|
|
60
60
|
/**
|
|
61
61
|
* Default branch for the generated regression-compare example (#243). From
|
package/dist/cli/i18n/en.d.ts
CHANGED
|
@@ -151,7 +151,7 @@ export declare const en: {
|
|
|
151
151
|
readonly 'help.option.analyze.skills': "Generate repo-specific skill files from detected communities (no-op when --index-only is also set).";
|
|
152
152
|
readonly 'help.option.analyze.skipAgentsMd': "Skip updating the gitnexus section in AGENTS.md and CLAUDE.md";
|
|
153
153
|
readonly 'help.option.analyze.noStats': "Omit volatile file/symbol counts from AGENTS.md and CLAUDE.md";
|
|
154
|
-
readonly 'help.option.analyze.skipSkills': "Skip installing standard GitNexus skill files under .claude/skills
|
|
154
|
+
readonly 'help.option.analyze.skipSkills': "Skip installing standard GitNexus skill files directly under .claude/skills/. Does not suppress community skills from --skills (those use .claude/skills/gitnexus-area-*). Use --index-only to skip all AI-context file injection.";
|
|
155
155
|
readonly 'help.option.analyze.indexOnly': "Pure index mode: skip all file injection (AGENTS.md, CLAUDE.md, skills)";
|
|
156
156
|
readonly 'help.option.skipGit': "Treat the provided path/cwd as the index root and skip parent git-root discovery";
|
|
157
157
|
readonly 'help.option.analyze.name': "Register this repo under a custom name in ~/.gitnexus/registry.json (disambiguates repos whose paths share a basename, e.g. two different .../app folders)";
|
package/dist/cli/i18n/en.js
CHANGED
|
@@ -151,7 +151,7 @@ export const en = {
|
|
|
151
151
|
'help.option.analyze.skills': 'Generate repo-specific skill files from detected communities (no-op when --index-only is also set).',
|
|
152
152
|
'help.option.analyze.skipAgentsMd': 'Skip updating the gitnexus section in AGENTS.md and CLAUDE.md',
|
|
153
153
|
'help.option.analyze.noStats': 'Omit volatile file/symbol counts from AGENTS.md and CLAUDE.md',
|
|
154
|
-
'help.option.analyze.skipSkills': 'Skip installing standard GitNexus skill files under .claude/skills
|
|
154
|
+
'help.option.analyze.skipSkills': 'Skip installing standard GitNexus skill files directly under .claude/skills/. Does not suppress community skills from --skills (those use .claude/skills/gitnexus-area-*). Use --index-only to skip all AI-context file injection.',
|
|
155
155
|
'help.option.analyze.indexOnly': 'Pure index mode: skip all file injection (AGENTS.md, CLAUDE.md, skills)',
|
|
156
156
|
'help.option.skipGit': 'Treat the provided path/cwd as the index root and skip parent git-root discovery',
|
|
157
157
|
'help.option.analyze.name': 'Register this repo under a custom name in ~/.gitnexus/registry.json (disambiguates repos whose paths share a basename, e.g. two different .../app folders)',
|
|
@@ -152,7 +152,7 @@ export declare const cliResources: {
|
|
|
152
152
|
readonly 'help.option.analyze.skills': "Generate repo-specific skill files from detected communities (no-op when --index-only is also set).";
|
|
153
153
|
readonly 'help.option.analyze.skipAgentsMd': "Skip updating the gitnexus section in AGENTS.md and CLAUDE.md";
|
|
154
154
|
readonly 'help.option.analyze.noStats': "Omit volatile file/symbol counts from AGENTS.md and CLAUDE.md";
|
|
155
|
-
readonly 'help.option.analyze.skipSkills': "Skip installing standard GitNexus skill files under .claude/skills
|
|
155
|
+
readonly 'help.option.analyze.skipSkills': "Skip installing standard GitNexus skill files directly under .claude/skills/. Does not suppress community skills from --skills (those use .claude/skills/gitnexus-area-*). Use --index-only to skip all AI-context file injection.";
|
|
156
156
|
readonly 'help.option.analyze.indexOnly': "Pure index mode: skip all file injection (AGENTS.md, CLAUDE.md, skills)";
|
|
157
157
|
readonly 'help.option.skipGit': "Treat the provided path/cwd as the index root and skip parent git-root discovery";
|
|
158
158
|
readonly 'help.option.analyze.name': "Register this repo under a custom name in ~/.gitnexus/registry.json (disambiguates repos whose paths share a basename, e.g. two different .../app folders)";
|
package/dist/cli/i18n/zh-CN.js
CHANGED
|
@@ -151,7 +151,7 @@ export const zhCN = {
|
|
|
151
151
|
'help.option.analyze.skills': '根据检测到的社区生成仓库专属 skill 文件(同时设置 --index-only 时无效)。',
|
|
152
152
|
'help.option.analyze.skipAgentsMd': '跳过更新 AGENTS.md 和 CLAUDE.md 中的 gitnexus 区块',
|
|
153
153
|
'help.option.analyze.noStats': '从 AGENTS.md 和 CLAUDE.md 中省略易变的文件/符号计数',
|
|
154
|
-
'help.option.analyze.skipSkills': '
|
|
154
|
+
'help.option.analyze.skipSkills': '跳过直接安装在 .claude/skills/ 下的标准 GitNexus skill 文件。不抑制 --skills 生成的社区 skill(位于 .claude/skills/gitnexus-area-*)。使用 --index-only 可跳过所有 AI 上下文文件注入。',
|
|
155
155
|
'help.option.analyze.indexOnly': '纯索引模式:跳过所有文件注入(AGENTS.md、CLAUDE.md、skills)',
|
|
156
156
|
'help.option.skipGit': '将提供的路径/cwd 视为索引根目录,并跳过向上查找 git 根目录',
|
|
157
157
|
'help.option.analyze.name': '在 ~/.gitnexus/registry.json 中使用自定义名称注册该仓库(用于区分路径 basename 相同的仓库,例如两个不同的 .../app 目录)',
|
package/dist/cli/index.js
CHANGED
|
@@ -53,8 +53,8 @@ program
|
|
|
53
53
|
'Without this flag, analyze always updates the workspace index, which follows the ' +
|
|
54
54
|
'checked-out working tree. Distinct from --default-branch (cosmetic base_ref).')
|
|
55
55
|
.option('--no-stats', 'Omit volatile file/symbol counts from AGENTS.md and CLAUDE.md')
|
|
56
|
-
.option('--skip-skills', 'Skip installing standard GitNexus skill files under .claude/skills
|
|
57
|
-
'Does not suppress community skills from --skills (those use .claude/skills/
|
|
56
|
+
.option('--skip-skills', 'Skip installing standard GitNexus skill files directly under .claude/skills/. ' +
|
|
57
|
+
'Does not suppress community skills from --skills (those use .claude/skills/gitnexus-area-*). ' +
|
|
58
58
|
'Use --index-only to skip all AI-context file injection.')
|
|
59
59
|
.option('--index-only', 'Pure index mode: skip all file injection (AGENTS.md, CLAUDE.md, skills)')
|
|
60
60
|
.option('--skip-git', 'Treat the provided path/cwd as the index root and skip parent git-root discovery')
|
package/dist/cli/skill-gen.js
CHANGED
|
@@ -8,6 +8,9 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import fs from 'fs/promises';
|
|
10
10
|
import path from 'path';
|
|
11
|
+
const GENERATED_SKILL_PREFIX = 'gitnexus-area-';
|
|
12
|
+
const MAX_SKILL_NAME_LENGTH = 64;
|
|
13
|
+
const MAX_COMMUNITY_NAME_LENGTH = MAX_SKILL_NAME_LENGTH - GENERATED_SKILL_PREFIX.length;
|
|
11
14
|
// ============================================================================
|
|
12
15
|
// MAIN EXPORT
|
|
13
16
|
// ============================================================================
|
|
@@ -20,7 +23,27 @@ import path from 'path';
|
|
|
20
23
|
*/
|
|
21
24
|
export const generateSkillFiles = async (repoPath, projectName, pipelineResult) => {
|
|
22
25
|
const { communityResult, processResult, graph } = pipelineResult;
|
|
23
|
-
const outputDir = path.join(repoPath, '.claude', 'skills'
|
|
26
|
+
const outputDir = path.join(repoPath, '.claude', 'skills');
|
|
27
|
+
const legacyOutputDir = path.join(outputDir, 'generated');
|
|
28
|
+
// Community skills used to live under an undiscoverable `generated/`
|
|
29
|
+
// grouping directory. Clear that GitNexus-owned legacy output and
|
|
30
|
+
// stale direct outputs in the reserved namespace, while preserving every
|
|
31
|
+
// unrelated project skill under .claude/skills/.
|
|
32
|
+
try {
|
|
33
|
+
const entries = await fs.readdir(outputDir, { withFileTypes: true });
|
|
34
|
+
await Promise.all(entries
|
|
35
|
+
.filter((entry) => entry.isDirectory() && entry.name.startsWith(GENERATED_SKILL_PREFIX))
|
|
36
|
+
.map((entry) => fs.rm(path.join(outputDir, entry.name), { recursive: true, force: true })));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
/* output root may not exist yet */
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
await fs.rm(legacyOutputDir, { recursive: true, force: true });
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
/* legacy output may not exist */
|
|
46
|
+
}
|
|
24
47
|
if (!communityResult || !communityResult.memberships.length) {
|
|
25
48
|
console.log('\n Skills: no communities detected, skipping skill generation');
|
|
26
49
|
return { skills: [], outputPath: outputDir };
|
|
@@ -47,13 +70,8 @@ export const generateSkillFiles = async (repoPath, projectName, pipelineResult)
|
|
|
47
70
|
// Step 3: Build lookup maps
|
|
48
71
|
const membershipsByComm = buildMembershipMap(communityResult.memberships);
|
|
49
72
|
const nodeIdToCommunityLabel = buildNodeCommunityLabelMap(communityResult.memberships, communities);
|
|
50
|
-
// Step 4:
|
|
51
|
-
|
|
52
|
-
await fs.rm(outputDir, { recursive: true, force: true });
|
|
53
|
-
}
|
|
54
|
-
catch {
|
|
55
|
-
/* may not exist */
|
|
56
|
-
}
|
|
73
|
+
// Step 4: Ensure the shared project-skill root exists. Never clear it: it
|
|
74
|
+
// also contains user-authored and standard GitNexus skills.
|
|
57
75
|
await fs.mkdir(outputDir, { recursive: true });
|
|
58
76
|
// Step 5: Generate skill files
|
|
59
77
|
const skills = [];
|
|
@@ -74,14 +92,15 @@ export const generateSkillFiles = async (repoPath, projectName, pipelineResult)
|
|
|
74
92
|
// Generate kebab name
|
|
75
93
|
const kebabName = toKebabName(community.label, usedNames);
|
|
76
94
|
usedNames.add(kebabName);
|
|
95
|
+
const skillName = `${GENERATED_SKILL_PREFIX}${kebabName}`;
|
|
77
96
|
// Generate SKILL.md content
|
|
78
|
-
const content = renderSkillMarkdown(community, projectName, members, files, entryPoints, flows, connections,
|
|
97
|
+
const content = renderSkillMarkdown(community, projectName, members, files, entryPoints, flows, connections, skillName);
|
|
79
98
|
// Write file
|
|
80
|
-
const skillDir = path.join(outputDir,
|
|
99
|
+
const skillDir = path.join(outputDir, skillName);
|
|
81
100
|
await fs.mkdir(skillDir, { recursive: true });
|
|
82
101
|
await fs.writeFile(path.join(skillDir, 'SKILL.md'), content, 'utf-8');
|
|
83
102
|
const info = {
|
|
84
|
-
name:
|
|
103
|
+
name: skillName,
|
|
85
104
|
label: community.label,
|
|
86
105
|
symbolCount: community.symbolCount,
|
|
87
106
|
fileCount: files.length,
|
|
@@ -89,7 +108,7 @@ export const generateSkillFiles = async (repoPath, projectName, pipelineResult)
|
|
|
89
108
|
skills.push(info);
|
|
90
109
|
console.log(` \u2713 ${community.label} (${community.symbolCount} symbols, ${files.length} files)`);
|
|
91
110
|
}
|
|
92
|
-
console.log(`\n ${skills.length} skills generated \u2192 .claude/skills
|
|
111
|
+
console.log(`\n ${skills.length} skills generated \u2192 .claude/skills/${GENERATED_SKILL_PREFIX}*/`);
|
|
93
112
|
return { skills, outputPath: outputDir };
|
|
94
113
|
};
|
|
95
114
|
// ============================================================================
|
|
@@ -380,10 +399,10 @@ const gatherCrossConnections = (rawIds, ownLabel, membershipsByComm, nodeIdToCom
|
|
|
380
399
|
* @param {MemberSymbol[]} entryPoints - Exported entry point symbols
|
|
381
400
|
* @param {ProcessNode[]} flows - Execution flows touching this community
|
|
382
401
|
* @param {CrossConnection[]} connections - Cross-community connections
|
|
383
|
-
* @param {string}
|
|
402
|
+
* @param {string} skillName - Namespaced kebab-case name for the skill
|
|
384
403
|
* @returns {string} Full SKILL.md content
|
|
385
404
|
*/
|
|
386
|
-
const renderSkillMarkdown = (community, projectName, members, files, entryPoints, flows, connections,
|
|
405
|
+
const renderSkillMarkdown = (community, projectName, members, files, entryPoints, flows, connections, skillName) => {
|
|
387
406
|
const cohesionPct = Math.round(community.cohesion * 100);
|
|
388
407
|
// Dominant directory: most common top-level directory
|
|
389
408
|
const dominantDir = getDominantDirectory(files);
|
|
@@ -396,7 +415,7 @@ const renderSkillMarkdown = (community, projectName, members, files, entryPoints
|
|
|
396
415
|
const lines = [];
|
|
397
416
|
// Frontmatter
|
|
398
417
|
lines.push('---');
|
|
399
|
-
lines.push(`name: ${
|
|
418
|
+
lines.push(`name: ${skillName}`);
|
|
400
419
|
lines.push(`description: "Skill for the ${community.label} area of ${projectName}. ${community.symbolCount} symbols across ${files.length} files."`);
|
|
401
420
|
lines.push('---');
|
|
402
421
|
lines.push('');
|
|
@@ -496,20 +515,21 @@ const renderSkillMarkdown = (community, projectName, members, files, entryPoints
|
|
|
496
515
|
* @brief Convert a community label to a kebab-case directory name
|
|
497
516
|
* @param {string} label - The community label
|
|
498
517
|
* @param {Set<string>} usedNames - Already-used names for collision detection
|
|
499
|
-
* @returns {string} Unique kebab-case name
|
|
518
|
+
* @returns {string} Unique kebab-case name that leaves room for the GitNexus prefix
|
|
500
519
|
*/
|
|
501
520
|
const toKebabName = (label, usedNames) => {
|
|
502
521
|
let name = label
|
|
503
522
|
.toLowerCase()
|
|
504
523
|
.replace(/[^a-z0-9]+/g, '-')
|
|
505
524
|
.replace(/^-+|-+$/g, '')
|
|
506
|
-
.slice(0,
|
|
525
|
+
.slice(0, MAX_COMMUNITY_NAME_LENGTH);
|
|
507
526
|
if (!name)
|
|
508
527
|
name = 'skill';
|
|
509
528
|
let candidate = name;
|
|
510
529
|
let counter = 2;
|
|
511
530
|
while (usedNames.has(candidate)) {
|
|
512
|
-
|
|
531
|
+
const suffix = `-${counter}`;
|
|
532
|
+
candidate = `${name.slice(0, MAX_COMMUNITY_NAME_LENGTH - suffix.length)}${suffix}`;
|
|
513
533
|
counter++;
|
|
514
534
|
}
|
|
515
535
|
return candidate;
|
|
@@ -47,7 +47,7 @@ export interface AnalyzeOptions {
|
|
|
47
47
|
skipAgentsMd?: boolean;
|
|
48
48
|
/** Omit volatile symbol/relationship counts from AGENTS.md and CLAUDE.md. */
|
|
49
49
|
noStats?: boolean;
|
|
50
|
-
/** Skip installing standard GitNexus skill files
|
|
50
|
+
/** Skip installing standard GitNexus skill files directly under .claude/skills/. */
|
|
51
51
|
skipSkills?: boolean;
|
|
52
52
|
/**
|
|
53
53
|
* Build the CFG/PDG substrate (#2081 M1). Forwarded to `PipelineOptions.pdg`,
|
package/package.json
CHANGED