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
36 changes: 31 additions & 5 deletions commands/sync-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,33 @@ const scope = scopeArg ? scopeArg.split('=')[1] : 'recent';
const pathArg = args.find(a => !a.startsWith('--') && a !== 'report' && a !== 'apply');
```

### Step 2: Spawn sync-docs-agent
### Step 2: Pre-fetch repo-intel doc-drift data

```javascript
let repoIntelContext = '';
try {
const { binary } = require('@agentsys/lib');
const fs = require('fs');
const path = require('path');
const cwd = process.cwd();
const stateDir = ['.claude', '.opencode', '.codex'].find(d => fs.existsSync(path.join(cwd, d))) || '.claude';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This logic for determining stateDir is duplicated in skills/sync-docs/SKILL.md. To improve maintainability and adhere to the DRY (Don't Repeat Yourself) principle, consider centralizing this logic. The @agentsys/lib library appears to provide xplat.getStateDir() which could potentially be used here and in other places where this logic is repeated.

const mapFile = path.join(cwd, stateDir, 'repo-intel.json');

if (fs.existsSync(mapFile)) {
const docDrift = JSON.parse(binary.runAnalyzer(['repo-intel', 'query', 'doc-drift', '--top', '20', '--map-file', mapFile, cwd]));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The value '20' is used here as a magic number. For better readability and maintainability, it's recommended to define it as a constant at the top of the script block, e.g., const TOP_N_DOC_DRIFT = '20';, and use this constant here.

if (docDrift.length > 0) {
const stale = docDrift.filter(d => d.codeCoupling === 0).map(d => d.path);
repoIntelContext = '\n\nRepo-intel doc-drift data (use this, do not re-scan):';
if (stale.length > 0) {
repoIntelContext += '\nDocs with ZERO code coupling (likely stale, check these first): ' + stale.join(', ');
}
repoIntelContext += '\nFull doc-drift data: ' + JSON.stringify(docDrift);
}
}
} catch (e) { /* unavailable */ }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Silently catching and ignoring errors can hide issues and make debugging difficult. While this feature might be opportunistic, logging the error (e.g., using console.warn) would provide valuable diagnostic information without interrupting the application's flow.

Suggested change
} catch (e) { /* unavailable */ }
} catch (e) { console.warn('Failed to pre-fetch repo-intel doc-drift data:', e); }

```

### Step 3: Spawn sync-docs-agent

```javascript
const agentOutput = await Task({
Expand All @@ -65,11 +91,11 @@ Mode: ${mode}
Scope: ${scope}
${pathArg ? `Path: ${pathArg}` : ''}

Execute the sync-docs skill and return structured results.`
Execute the sync-docs skill and return structured results.${repoIntelContext}`
});
```

### Step 3: Process Results
### Step 4: Process Results

Parse the structured JSON from between `=== SYNC_DOCS_RESULT ===` markers:

Expand All @@ -87,7 +113,7 @@ const result = parseSyncDocsResult(agentOutput);
// result now contains: { mode, scope, validation, discovery, issues, fixes, changelog, summary }
```

### Step 4: Apply Fixes (if apply mode)
### Step 5: Apply Fixes (if apply mode)

If mode is `apply` and fixes array is non-empty:

Expand All @@ -104,7 +130,7 @@ Use the Edit tool to apply each fix. Commit message: "docs: sync documentation w
}
```

### Step 5: Present Results
### Step 6: Present Results

```markdown
## Documentation Sync ${mode === 'apply' ? 'Applied' : 'Report'}
Expand Down
39 changes: 39 additions & 0 deletions skills/sync-docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: sync-docs
description: "Sync documentation with code. Use when user asks to update docs, check docs, fix stale documentation, update changelog, or after code changes."
version: 5.1.0

Check notice on line 4 in skills/sync-docs/SKILL.md

View workflow job for this annotation

GitHub Actions / agnix / agnix

skill uses client-specific field 'version' which is not part of the universal Agent Skills spec [XP-SK-001]
argument-hint: "[report|apply] [--scope=all|recent|before-pr] [--include-undocumented]"

Check notice on line 5 in skills/sync-docs/SKILL.md

View workflow job for this annotation

GitHub Actions / agnix / agnix

skill uses client-specific field 'argument-hint' which is not part of the universal Agent Skills spec [XP-SK-001]
allowed-tools: Bash(git:*), Read, Grep, Glob
---

Expand All @@ -21,6 +21,45 @@

## Quick Start - Agent Instructions

### Pre-check: Ensure Repo-Intel

Before starting analysis, check if the repo-intel map exists:

```javascript
const fs = require('fs');
const path = require('path');

const cwd = process.cwd();
const stateDir = ['.claude', '.opencode', '.codex']
.find(d => fs.existsSync(path.join(cwd, d))) || '.claude';
Comment on lines +33 to +34
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This logic for determining stateDir is duplicated in commands/sync-docs.md. To improve maintainability and adhere to the DRY (Don't Repeat Yourself) principle, this logic should be centralized. The @agentsys/lib library appears to provide xplat.getStateDir() which could potentially be used. Using a shared utility would require some refactoring here, as the require for @agentsys/lib is currently inside a conditional block.

const mapFile = path.join(cwd, stateDir, 'repo-intel.json');

if (!fs.existsSync(mapFile)) {
const response = await AskUserQuestion({
questions: [{
question: 'Generate repo-intel?',
description: 'No repo-intel map found. Generating one enables doc-drift detection (identifies stale docs by code coupling). Takes ~5 seconds.',
options: [
{ label: 'Yes, generate it', value: 'yes' },
{ label: 'Skip', value: 'no' }
]
}]
});

if (response === 'yes' || response?.['Generate repo-intel?'] === 'yes') {
try {
const { binary } = require('@agentsys/lib');
const output = binary.runAnalyzer(['repo-intel', 'init', cwd]);
const stateDirPath = path.join(cwd, stateDir);
if (!fs.existsSync(stateDirPath)) fs.mkdirSync(stateDirPath, { recursive: true });
fs.writeFileSync(mapFile, output);
} catch (e) {
// Binary not available - proceed without
}
Comment on lines +56 to +58
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Silently catching and ignoring errors can hide issues and make debugging difficult. Even if the binary is unavailable, logging the error (e.g., using console.warn) would provide valuable diagnostic information for developers without interrupting the user's flow.

Suggested change
} catch (e) {
// Binary not available - proceed without
}
} catch (e) {
console.warn('Failed to generate repo-intel map:', e);
// Binary not available or failed to run - proceed without
}

}
}
```

**Step 1**: Get changed files (use Bash):
```bash
# Recent changes (default scope)
Expand Down
Loading