ace-docs 0.31.0
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.
- checksums.yaml +7 -0
- data/.ace-defaults/docs/config.yml +169 -0
- data/.ace-defaults/docs/multi-subject-example.md +130 -0
- data/.ace-defaults/docs/single-subject-example.md +150 -0
- data/.ace-defaults/nav/protocols/guide-sources/ace-docs.yml +10 -0
- data/.ace-defaults/nav/protocols/prompt-sources/ace-docs.yml +34 -0
- data/.ace-defaults/nav/protocols/tmpl-sources/ace-docs.yml +10 -0
- data/.ace-defaults/nav/protocols/wfi-sources/ace-docs.yml +19 -0
- data/CHANGELOG.md +1082 -0
- data/LICENSE +21 -0
- data/README.md +40 -0
- data/Rakefile +14 -0
- data/exe/ace-docs +14 -0
- data/handbook/guides/documentation/ruby.md +16 -0
- data/handbook/guides/documentation/rust.md +35 -0
- data/handbook/guides/documentation/typescript.md +18 -0
- data/handbook/guides/documentation.g.md +437 -0
- data/handbook/guides/documents-embedded-sync.g.md +473 -0
- data/handbook/guides/documents-embedding.g.md +276 -0
- data/handbook/guides/markdown-style.g.md +290 -0
- data/handbook/prompts/ace-change-analyzer.system.md +113 -0
- data/handbook/prompts/ace-change-analyzer.user.md +95 -0
- data/handbook/prompts/document-analysis.md +74 -0
- data/handbook/prompts/document-analysis.system.md +129 -0
- data/handbook/prompts/markdown-style.system.md +113 -0
- data/handbook/skills/as-docs-create-adr/SKILL.md +35 -0
- data/handbook/skills/as-docs-create-api/SKILL.md +35 -0
- data/handbook/skills/as-docs-create-user/SKILL.md +35 -0
- data/handbook/skills/as-docs-maintain-adrs/SKILL.md +35 -0
- data/handbook/skills/as-docs-squash-changelog/SKILL.md +42 -0
- data/handbook/skills/as-docs-update/SKILL.md +36 -0
- data/handbook/skills/as-docs-update-blueprint/SKILL.md +28 -0
- data/handbook/skills/as-docs-update-roadmap/SKILL.md +24 -0
- data/handbook/skills/as-docs-update-tools/SKILL.md +36 -0
- data/handbook/skills/as-docs-update-usage/SKILL.md +26 -0
- data/handbook/templates/code-docs/javascript-jsdoc.template.md +102 -0
- data/handbook/templates/code-docs/ruby-yard.template.md +85 -0
- data/handbook/templates/project-docs/README.template.md +73 -0
- data/handbook/templates/project-docs/architecture.template.md +300 -0
- data/handbook/templates/project-docs/blueprint.template.md +165 -0
- data/handbook/templates/project-docs/context/ownership.yml +160 -0
- data/handbook/templates/project-docs/decisions/adr.template.md +60 -0
- data/handbook/templates/project-docs/prd.template.md +144 -0
- data/handbook/templates/project-docs/roadmap/roadmap.template.md +47 -0
- data/handbook/templates/project-docs/vision.template.md +233 -0
- data/handbook/templates/user-docs/user-guide.template.md +107 -0
- data/handbook/workflow-instructions/docs/create-adr.wf.md +334 -0
- data/handbook/workflow-instructions/docs/create-api.wf.md +448 -0
- data/handbook/workflow-instructions/docs/create-cookbook.wf.md +434 -0
- data/handbook/workflow-instructions/docs/create-user.wf.md +399 -0
- data/handbook/workflow-instructions/docs/maintain-adrs.wf.md +589 -0
- data/handbook/workflow-instructions/docs/squash-changelog.wf.md +246 -0
- data/handbook/workflow-instructions/docs/update-blueprint.wf.md +361 -0
- data/handbook/workflow-instructions/docs/update-context.wf.md +336 -0
- data/handbook/workflow-instructions/docs/update-roadmap.wf.md +421 -0
- data/handbook/workflow-instructions/docs/update-tools.wf.md +307 -0
- data/handbook/workflow-instructions/docs/update-usage.wf.md +710 -0
- data/handbook/workflow-instructions/docs/update.wf.md +418 -0
- data/lib/ace/docs/atoms/diff_filterer.rb +131 -0
- data/lib/ace/docs/atoms/frontmatter_free_matcher.rb +20 -0
- data/lib/ace/docs/atoms/git_date_resolver.rb +16 -0
- data/lib/ace/docs/atoms/readme_metadata_inferrer.rb +60 -0
- data/lib/ace/docs/atoms/terminology_extractor.rb +308 -0
- data/lib/ace/docs/atoms/time_range_calculator.rb +96 -0
- data/lib/ace/docs/atoms/timestamp_parser.rb +106 -0
- data/lib/ace/docs/atoms/type_inferrer.rb +70 -0
- data/lib/ace/docs/cli/commands/analyze.rb +351 -0
- data/lib/ace/docs/cli/commands/analyze_consistency.rb +185 -0
- data/lib/ace/docs/cli/commands/discover.rb +75 -0
- data/lib/ace/docs/cli/commands/scope_options.rb +71 -0
- data/lib/ace/docs/cli/commands/status.rb +241 -0
- data/lib/ace/docs/cli/commands/update.rb +198 -0
- data/lib/ace/docs/cli/commands/validate.rb +225 -0
- data/lib/ace/docs/cli.rb +60 -0
- data/lib/ace/docs/models/analysis_report.rb +120 -0
- data/lib/ace/docs/models/consistency_report.rb +259 -0
- data/lib/ace/docs/models/document.rb +354 -0
- data/lib/ace/docs/molecules/change_detector.rb +389 -0
- data/lib/ace/docs/molecules/document_loader.rb +133 -0
- data/lib/ace/docs/molecules/frontmatter_manager.rb +85 -0
- data/lib/ace/docs/molecules/git_date_resolver.rb +30 -0
- data/lib/ace/docs/organisms/cross_document_analyzer.rb +274 -0
- data/lib/ace/docs/organisms/document_registry.rb +318 -0
- data/lib/ace/docs/organisms/validator.rb +164 -0
- data/lib/ace/docs/prompts/compact_diff_prompt.rb +119 -0
- data/lib/ace/docs/prompts/consistency_prompt.rb +286 -0
- data/lib/ace/docs/prompts/document_analysis_prompt.rb +389 -0
- data/lib/ace/docs/version.rb +7 -0
- data/lib/ace/docs.rb +82 -0
- data/lib/test.rb +4 -0
- metadata +347 -0
|
@@ -0,0 +1,418 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: workflow
|
|
3
|
+
title: Update Documentation with ace-docs
|
|
4
|
+
purpose: Update documentation with ace-docs tool orchestration
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: 2026-03-08
|
|
7
|
+
last-checked: 2026-03-21
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Update Documentation with ace-docs
|
|
11
|
+
|
|
12
|
+
Orchestrate ace-docs tools for iterative documentation updates through agent/human collaboration.
|
|
13
|
+
|
|
14
|
+
## Quick Start
|
|
15
|
+
|
|
16
|
+
### Specific File Update (Direct Path)
|
|
17
|
+
|
|
18
|
+
When updating a specific document, go straight to analysis:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Analyze specific document immediately
|
|
22
|
+
ace-docs analyze docs/api.md
|
|
23
|
+
|
|
24
|
+
# Review the analysis report
|
|
25
|
+
cat .ace-local/docs/analyze-*/analysis.md
|
|
26
|
+
|
|
27
|
+
# Update document based on recommendations
|
|
28
|
+
ace-docs update docs/api.md --set last-updated=today
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Bulk Update (Status Check First)
|
|
32
|
+
|
|
33
|
+
When updating multiple documents or checking what needs updates:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Check which documents need updates
|
|
37
|
+
ace-docs status --needs-update
|
|
38
|
+
|
|
39
|
+
# Analyze all documents needing updates
|
|
40
|
+
ace-docs analyze --needs-update
|
|
41
|
+
|
|
42
|
+
# Review analysis report and update documents
|
|
43
|
+
cat .ace-local/docs/analyze-*/analysis.md
|
|
44
|
+
ace-docs update [file] --set last-updated=today
|
|
45
|
+
|
|
46
|
+
# Or filter by type
|
|
47
|
+
ace-docs status --type guide
|
|
48
|
+
ace-docs analyze --all --type guide
|
|
49
|
+
|
|
50
|
+
# Scope to one package
|
|
51
|
+
ace-docs status --package ace-assign
|
|
52
|
+
ace-docs validate --package ace-assign --all
|
|
53
|
+
|
|
54
|
+
# Scope with glob (bare package path is normalized)
|
|
55
|
+
ace-docs status --glob ace-assign
|
|
56
|
+
ace-docs validate --glob "ace-assign/docs/**/*.md" --syntax
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Input Handling
|
|
60
|
+
|
|
61
|
+
Accept flexible input for document selection:
|
|
62
|
+
|
|
63
|
+
### Direct Analysis (Skip Status Check)
|
|
64
|
+
|
|
65
|
+
When specific file(s) are provided, the workflow proceeds directly to analysis:
|
|
66
|
+
|
|
67
|
+
1. **Specific documents**: List of file paths
|
|
68
|
+
- `docs/api.md handbook/guide.md`
|
|
69
|
+
- Goes straight to `ace-docs analyze [files]`
|
|
70
|
+
|
|
71
|
+
### Status-First (Check What Needs Updates)
|
|
72
|
+
|
|
73
|
+
When using filters or bulk operations, the workflow starts with status check:
|
|
74
|
+
|
|
75
|
+
2. **Preset selection**: Use configured preset
|
|
76
|
+
- `--preset standard`
|
|
77
|
+
3. **Type filtering**: Update by document type
|
|
78
|
+
- `--type guide`
|
|
79
|
+
4. **Scope filtering**: Restrict by package or path glob
|
|
80
|
+
- `--package ace-assign`
|
|
81
|
+
- `--glob ace-assign` (normalized to `ace-assign/**/*.md`)
|
|
82
|
+
- `--glob "ace-assign/docs/**/*.md"`
|
|
83
|
+
5. **Status-based**: Documents needing update
|
|
84
|
+
- `--needs-update` (default when no files specified)
|
|
85
|
+
6. **All documents**: Process everything
|
|
86
|
+
- `--all`
|
|
87
|
+
|
|
88
|
+
**Decision Rule**: If specific file paths are provided → skip to analysis. Otherwise → start with status check.
|
|
89
|
+
|
|
90
|
+
## Workflow Steps
|
|
91
|
+
|
|
92
|
+
### Decision Point: Specific File or Bulk Operation?
|
|
93
|
+
|
|
94
|
+
**If specific file(s) provided** → Skip to Step 2 (Analyze Documents)
|
|
95
|
+
**If bulk/filter operation** → Start at Step 1 (Load Document Status)
|
|
96
|
+
|
|
97
|
+
### 1. Load Document Status (Bulk Operations Only)
|
|
98
|
+
|
|
99
|
+
**Skip this step if specific file(s) were provided.**
|
|
100
|
+
|
|
101
|
+
For bulk operations, check current state of managed documents:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
ace-docs status [options]
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Review the table showing:
|
|
108
|
+
- Document names and types
|
|
109
|
+
- Last updated dates
|
|
110
|
+
- Freshness status (current/stale/outdated)
|
|
111
|
+
- Update frequency configuration
|
|
112
|
+
|
|
113
|
+
If no documents match criteria, exit with message.
|
|
114
|
+
|
|
115
|
+
### 2. Analyze Documents (Always Required)
|
|
116
|
+
|
|
117
|
+
Generate LLM-powered analysis for selected documents:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
ace-docs analyze [file|--all|--needs-update] [options]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Options:
|
|
124
|
+
- `--since DATE`: Analyze from specific date/commit
|
|
125
|
+
- `--exclude-renames`: Skip renamed files
|
|
126
|
+
- `--exclude-moves`: Skip moved files
|
|
127
|
+
|
|
128
|
+
The analysis is saved to `.ace-local/docs/analyze-{timestamp}/analysis.md`
|
|
129
|
+
|
|
130
|
+
**Note**: The analyze directory contains additional files (context.md, *.diff, prompts) for debugging purposes only. The workflow uses `analysis.md` as the primary output.
|
|
131
|
+
|
|
132
|
+
**Decision Point**: If no changes detected, exit workflow.
|
|
133
|
+
|
|
134
|
+
### 2.5 Review Analysis Report
|
|
135
|
+
|
|
136
|
+
Read the generated analysis report:
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
cat .ace-local/docs/analyze-*/analysis.md
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The report contains:
|
|
143
|
+
- **Summary**: Overview of changes affecting the document
|
|
144
|
+
- **Changes Detected**: Categorized by priority (HIGH/MEDIUM/LOW)
|
|
145
|
+
- **Recommended Updates**: Specific sections to update with reasoning
|
|
146
|
+
- **Additional Notes**: Context and patterns to consider
|
|
147
|
+
|
|
148
|
+
Use these LLM recommendations to guide your document updates in the next step.
|
|
149
|
+
|
|
150
|
+
### 3. Review and Update Documents
|
|
151
|
+
|
|
152
|
+
For each document with changes:
|
|
153
|
+
|
|
154
|
+
#### a. Load Document Context
|
|
155
|
+
- Read current document content
|
|
156
|
+
- Review frontmatter configuration
|
|
157
|
+
- Note update focus areas if specified
|
|
158
|
+
|
|
159
|
+
#### b. Apply Analysis Recommendations
|
|
160
|
+
Using the analysis.md report:
|
|
161
|
+
- Focus on HIGH priority changes first
|
|
162
|
+
- Review specific "Recommended Updates" for the document
|
|
163
|
+
- Consider the reasoning provided for each recommendation
|
|
164
|
+
- Maintain document style while incorporating changes
|
|
165
|
+
|
|
166
|
+
#### c. Update Document Content
|
|
167
|
+
**Agent/Human Decision**: Based on changes:
|
|
168
|
+
- Update technical details
|
|
169
|
+
- Add new sections
|
|
170
|
+
- Remove outdated information
|
|
171
|
+
- Maintain document style/voice
|
|
172
|
+
|
|
173
|
+
#### d. Update Metadata
|
|
174
|
+
After content updates:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
ace-docs update [file] --set last-updated=today --set last-checked=today
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Additional metadata updates:
|
|
181
|
+
- Version numbers if applicable
|
|
182
|
+
- Custom metadata fields
|
|
183
|
+
- Context requirements
|
|
184
|
+
|
|
185
|
+
### 4. Validate Updates
|
|
186
|
+
|
|
187
|
+
Run validation on updated documents:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
ace-docs validate [file|pattern] [--syntax|--semantic|--all]
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Check for:
|
|
194
|
+
- Required frontmatter fields
|
|
195
|
+
- Max line limits
|
|
196
|
+
- Required sections
|
|
197
|
+
- Syntax errors (if linter available)
|
|
198
|
+
- Semantic issues (if LLM available)
|
|
199
|
+
|
|
200
|
+
### 5. Present Summary
|
|
201
|
+
|
|
202
|
+
Generate summary of updates:
|
|
203
|
+
- Number of documents updated
|
|
204
|
+
- Types of changes made
|
|
205
|
+
- Any validation issues
|
|
206
|
+
- Documents skipped/deferred
|
|
207
|
+
|
|
208
|
+
## Document-Specific Guidelines
|
|
209
|
+
|
|
210
|
+
### Tool Documentation (tools.md, reference docs)
|
|
211
|
+
|
|
212
|
+
When updating tool documentation and command references:
|
|
213
|
+
|
|
214
|
+
**Best Practices for Examples:**
|
|
215
|
+
- Only include meaningful, practical examples that demonstrate real usage
|
|
216
|
+
- Skip trivial commands like `--version`, `--help`, `-h`, `-v`
|
|
217
|
+
- Show actual usage that demonstrates the tool's purpose
|
|
218
|
+
- Aim for 2-4 practical examples per tool
|
|
219
|
+
- Focus on common use cases and workflows
|
|
220
|
+
|
|
221
|
+
**Example - Good:**
|
|
222
|
+
```bash
|
|
223
|
+
# Analyze documents needing updates
|
|
224
|
+
ace-docs status --needs-update
|
|
225
|
+
|
|
226
|
+
# Update specific document metadata
|
|
227
|
+
ace-docs update docs/api.md --set last-updated=today
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
**Example - Skip:**
|
|
231
|
+
```bash
|
|
232
|
+
ace-docs --version # Trivial, not useful
|
|
233
|
+
ace-docs -h # Help text, not practical usage
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Architecture Decision Records (ADRs)
|
|
237
|
+
|
|
238
|
+
For ADR lifecycle management (creation, evolution, archival, scope updates):
|
|
239
|
+
|
|
240
|
+
**Creating new ADRs:**
|
|
241
|
+
`wfi://docs/create-adr`
|
|
242
|
+
|
|
243
|
+
**Maintaining existing ADRs:**
|
|
244
|
+
`wfi://docs/maintain-adrs`
|
|
245
|
+
|
|
246
|
+
ADR maintenance includes:
|
|
247
|
+
- Evolution documentation when patterns change
|
|
248
|
+
- Archival of obsolete decisions
|
|
249
|
+
- Scope updates for partially outdated decisions
|
|
250
|
+
- Synchronization with `docs/decisions.md` summary
|
|
251
|
+
|
|
252
|
+
### Context Documents (vision.md, architecture.md, etc.)
|
|
253
|
+
|
|
254
|
+
For core context documents with specific requirements (line limits, update order, duplication prevention), see the specialized workflow:
|
|
255
|
+
|
|
256
|
+
`wfi://docs/update-context`
|
|
257
|
+
|
|
258
|
+
This workflow provides:
|
|
259
|
+
- Specific update order to prevent duplication
|
|
260
|
+
- Target line counts for each document
|
|
261
|
+
- Content ownership rules
|
|
262
|
+
- Cross-document validation
|
|
263
|
+
|
|
264
|
+
## Error Handling
|
|
265
|
+
|
|
266
|
+
- **Missing frontmatter**: Suggest adding ace-docs frontmatter
|
|
267
|
+
- **Validation failures**: Report specific issues, continue with other docs
|
|
268
|
+
- **Git errors**: Check repository state, suggest fixes
|
|
269
|
+
- **LLM unavailable**: The analyze command will fail - it requires LLM for generating recommendations
|
|
270
|
+
- **Empty analysis**: Check if document has subject configuration and if changes exist in the time period
|
|
271
|
+
|
|
272
|
+
## Integration Points
|
|
273
|
+
|
|
274
|
+
### With ace-bundle
|
|
275
|
+
Load project context for documentation:
|
|
276
|
+
```bash
|
|
277
|
+
ace-bundle --preset docs
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
### With LLM Analysis
|
|
281
|
+
The `ace-docs analyze` command automatically integrates with LLM for intelligent change analysis. The `analysis.md` output provides:
|
|
282
|
+
- Prioritized changes (HIGH/MEDIUM/LOW)
|
|
283
|
+
- Specific recommendations for document updates
|
|
284
|
+
- Context-aware reasoning
|
|
285
|
+
|
|
286
|
+
No manual LLM integration is needed - it's built into the analyze command.
|
|
287
|
+
|
|
288
|
+
### With git workflow
|
|
289
|
+
After updates, commit changes:
|
|
290
|
+
```bash
|
|
291
|
+
git add [updated-files]
|
|
292
|
+
git commit -m "docs: Update documentation via ace-docs
|
|
293
|
+
|
|
294
|
+
- Updated [list of documents]
|
|
295
|
+
- Synchronized with recent changes
|
|
296
|
+
- Validated against configured rules"
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Configuration
|
|
300
|
+
|
|
301
|
+
### Document Discovery
|
|
302
|
+
Configure in `.ace/docs/config.yml`:
|
|
303
|
+
```yaml
|
|
304
|
+
document_types:
|
|
305
|
+
guide:
|
|
306
|
+
paths: ["**/*.g.md", "handbook/guides/**/*.md"]
|
|
307
|
+
defaults:
|
|
308
|
+
update_frequency: monthly
|
|
309
|
+
api:
|
|
310
|
+
paths: ["*/docs/api/*.md"]
|
|
311
|
+
defaults:
|
|
312
|
+
update_frequency: on-change
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Multi-Subject Configuration
|
|
316
|
+
Configure multiple subjects in document frontmatter for categorized analysis:
|
|
317
|
+
```yaml
|
|
318
|
+
ace-docs:
|
|
319
|
+
subject:
|
|
320
|
+
- code:
|
|
321
|
+
diff:
|
|
322
|
+
paths: ["**/*.rb", "**/*.js"]
|
|
323
|
+
- config:
|
|
324
|
+
diff:
|
|
325
|
+
paths: ["**/*.yml", "**/*.yaml"]
|
|
326
|
+
- docs:
|
|
327
|
+
diff:
|
|
328
|
+
paths: ["**/*.md"]
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
The `analyze` command will generate separate diffs for each subject, providing more focused analysis.
|
|
332
|
+
|
|
333
|
+
### Global Rules
|
|
334
|
+
```yaml
|
|
335
|
+
global_rules:
|
|
336
|
+
max_lines: 1000
|
|
337
|
+
required_frontmatter: ["doc-type", "purpose"]
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Exit Conditions
|
|
341
|
+
|
|
342
|
+
Workflow exits when:
|
|
343
|
+
- No documents match selection criteria
|
|
344
|
+
- No changes detected in diff analysis
|
|
345
|
+
- All selected documents processed
|
|
346
|
+
- Critical error prevents continuation
|
|
347
|
+
|
|
348
|
+
## Usage Examples
|
|
349
|
+
|
|
350
|
+
### Update specific document (Direct Path)
|
|
351
|
+
```bash
|
|
352
|
+
# When you know exactly which document to update
|
|
353
|
+
# Skip status check and go straight to analysis
|
|
354
|
+
ace-docs analyze ace-docs/README.md
|
|
355
|
+
|
|
356
|
+
# Review the analysis report
|
|
357
|
+
cat .ace-local/docs/analyze-*/analysis.md
|
|
358
|
+
|
|
359
|
+
# Update document based on recommendations
|
|
360
|
+
# [Review analysis.md and update content]
|
|
361
|
+
ace-docs update ace-docs/README.md --set last-updated=today
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
### Update stale guides (Bulk Operation)
|
|
365
|
+
```bash
|
|
366
|
+
# Start with status check for bulk operations
|
|
367
|
+
ace-docs status --type guide --freshness stale
|
|
368
|
+
|
|
369
|
+
# Analyze changes and generate recommendations
|
|
370
|
+
ace-docs analyze --type guide --freshness stale
|
|
371
|
+
|
|
372
|
+
# Review the analysis report
|
|
373
|
+
cat .ace-local/docs/analyze-*/analysis.md
|
|
374
|
+
|
|
375
|
+
# Update each document based on recommendations
|
|
376
|
+
# [Review analysis.md and update content]
|
|
377
|
+
ace-docs update guide1.md --set last-updated=today
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Bulk metadata update
|
|
381
|
+
```bash
|
|
382
|
+
# Update all documents of a type
|
|
383
|
+
ace-docs update --preset standard --set version=2.0
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Pre-commit validation
|
|
387
|
+
```bash
|
|
388
|
+
# Validate all changed documents
|
|
389
|
+
ace-docs validate $(git diff --name-only -- '*.md')
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Analyze and update workflow
|
|
393
|
+
|
|
394
|
+
#### For specific file (direct):
|
|
395
|
+
```bash
|
|
396
|
+
# Direct analysis when you know the file
|
|
397
|
+
ace-docs analyze docs/architecture.md
|
|
398
|
+
cat .ace-local/docs/analyze-*/analysis.md
|
|
399
|
+
# Review recommendations and update document
|
|
400
|
+
ace-docs update docs/architecture.md --set last-updated=today
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
#### For bulk updates (status-first):
|
|
404
|
+
```bash
|
|
405
|
+
# Check what needs updating first
|
|
406
|
+
ace-docs status --needs-update
|
|
407
|
+
ace-docs analyze --needs-update
|
|
408
|
+
cat .ace-local/docs/analyze-*/analysis.md
|
|
409
|
+
# Review recommendations and update documents
|
|
410
|
+
ace-docs update [file] --set last-updated=today
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## Notes
|
|
414
|
+
|
|
415
|
+
- The workflow is designed for iterative updates with human/agent oversight
|
|
416
|
+
- Change analysis provides data, but update decisions remain with the operator
|
|
417
|
+
- Metadata-only updates are safe and reversible
|
|
418
|
+
- Content updates should be reviewed before committing
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ace
|
|
4
|
+
module Docs
|
|
5
|
+
module Atoms
|
|
6
|
+
# Pure functions for filtering diff content
|
|
7
|
+
class DiffFilterer
|
|
8
|
+
class << self
|
|
9
|
+
# Default patterns to exclude from diffs
|
|
10
|
+
DEFAULT_EXCLUDE_PATTERNS = [
|
|
11
|
+
%r{^test/},
|
|
12
|
+
%r{^spec/},
|
|
13
|
+
%r{\.test\.},
|
|
14
|
+
%r{\.spec\.},
|
|
15
|
+
%r{^coverage/},
|
|
16
|
+
%r{^tmp/},
|
|
17
|
+
%r{^vendor/},
|
|
18
|
+
%r{^node_modules/},
|
|
19
|
+
%r{^\.git/},
|
|
20
|
+
%r{Gemfile\.lock$},
|
|
21
|
+
%r{package-lock\.json$},
|
|
22
|
+
%r{yarn\.lock$}
|
|
23
|
+
].freeze
|
|
24
|
+
|
|
25
|
+
# Filter paths from diff output
|
|
26
|
+
# @param diff [String] The diff content
|
|
27
|
+
# @param exclude_patterns [Array<Regexp>] Patterns to exclude
|
|
28
|
+
# @return [String] Filtered diff content
|
|
29
|
+
def filter_paths(diff, exclude_patterns = DEFAULT_EXCLUDE_PATTERNS)
|
|
30
|
+
return "" if diff.nil? || diff.empty?
|
|
31
|
+
|
|
32
|
+
lines = diff.split("\n")
|
|
33
|
+
filtered_lines = []
|
|
34
|
+
skip_until_next_file = false
|
|
35
|
+
|
|
36
|
+
lines.each do |line|
|
|
37
|
+
# Check if this is a file header
|
|
38
|
+
if file_header?(line)
|
|
39
|
+
file_path = extract_file_path(line)
|
|
40
|
+
if should_exclude?(file_path, exclude_patterns)
|
|
41
|
+
skip_until_next_file = true
|
|
42
|
+
else
|
|
43
|
+
skip_until_next_file = false
|
|
44
|
+
filtered_lines << line
|
|
45
|
+
end
|
|
46
|
+
elsif !skip_until_next_file
|
|
47
|
+
filtered_lines << line
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
filtered_lines.join("\n")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Estimate the size of a diff in lines
|
|
55
|
+
# @param diff [String] The diff content
|
|
56
|
+
# @return [Integer] Number of lines
|
|
57
|
+
def estimate_size(diff)
|
|
58
|
+
return 0 if diff.nil? || diff.empty?
|
|
59
|
+
|
|
60
|
+
diff.count("\n") + 1
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Count significant changes (additions and deletions)
|
|
64
|
+
# @param diff [String] The diff content
|
|
65
|
+
# @return [Hash] Statistics about the diff
|
|
66
|
+
def count_changes(diff)
|
|
67
|
+
return {additions: 0, deletions: 0, files: 0} if diff.nil? || diff.empty?
|
|
68
|
+
|
|
69
|
+
additions = 0
|
|
70
|
+
deletions = 0
|
|
71
|
+
files = 0
|
|
72
|
+
|
|
73
|
+
diff.split("\n").each do |line|
|
|
74
|
+
if file_header?(line)
|
|
75
|
+
files += 1
|
|
76
|
+
elsif line.start_with?("+") && !line.start_with?("+++")
|
|
77
|
+
additions += 1
|
|
78
|
+
elsif line.start_with?("-") && !line.start_with?("---")
|
|
79
|
+
deletions += 1
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
{
|
|
84
|
+
additions: additions,
|
|
85
|
+
deletions: deletions,
|
|
86
|
+
files: files,
|
|
87
|
+
total_changes: additions + deletions
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Check if diff is too large for processing
|
|
92
|
+
# @param diff [String] The diff content
|
|
93
|
+
# @param max_lines [Integer] Maximum allowed lines
|
|
94
|
+
# @return [Boolean] True if diff exceeds limit
|
|
95
|
+
def exceeds_limit?(diff, max_lines = 100_000)
|
|
96
|
+
estimate_size(diff) > max_lines
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
# Check if a line is a file header in git diff format
|
|
102
|
+
def file_header?(line)
|
|
103
|
+
line.start_with?("diff --git", "+++", "---") ||
|
|
104
|
+
line.match?(/^index [a-f0-9]+\.\.[a-f0-9]+/)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Extract file path from diff header line
|
|
108
|
+
def extract_file_path(line)
|
|
109
|
+
case line
|
|
110
|
+
when /^diff --git a\/(.+) b\/(.+)$/
|
|
111
|
+
Regexp.last_match(2) # Use the 'b/' path (new file path)
|
|
112
|
+
when /^\+\+\+ b\/(.+)$/
|
|
113
|
+
Regexp.last_match(1)
|
|
114
|
+
when /^--- a\/(.+)$/
|
|
115
|
+
Regexp.last_match(1)
|
|
116
|
+
else
|
|
117
|
+
""
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Check if a file path should be excluded
|
|
122
|
+
def should_exclude?(file_path, patterns)
|
|
123
|
+
return false if file_path.empty?
|
|
124
|
+
|
|
125
|
+
patterns.any? { |pattern| file_path.match?(pattern) }
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ace/core/molecules/frontmatter_free_policy"
|
|
4
|
+
|
|
5
|
+
module Ace
|
|
6
|
+
module Docs
|
|
7
|
+
module Atoms
|
|
8
|
+
# Matches markdown files that are managed without frontmatter.
|
|
9
|
+
class FrontmatterFreeMatcher
|
|
10
|
+
def self.match?(path, patterns:, project_root: Dir.pwd)
|
|
11
|
+
Ace::Core::Molecules::FrontmatterFreePolicy.match?(
|
|
12
|
+
path,
|
|
13
|
+
patterns: patterns,
|
|
14
|
+
project_root: project_root
|
|
15
|
+
)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../molecules/git_date_resolver"
|
|
4
|
+
|
|
5
|
+
module Ace
|
|
6
|
+
module Docs
|
|
7
|
+
module Atoms
|
|
8
|
+
# Compatibility shim: delegated to molecule implementation.
|
|
9
|
+
class GitDateResolver
|
|
10
|
+
def self.last_updated_for(path)
|
|
11
|
+
Molecules::GitDateResolver.last_updated_for(path)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ace
|
|
4
|
+
module Docs
|
|
5
|
+
module Atoms
|
|
6
|
+
# Infers metadata for README files managed without frontmatter.
|
|
7
|
+
class ReadmeMetadataInferrer
|
|
8
|
+
def self.infer(path:, content:, last_updated: nil)
|
|
9
|
+
return nil unless File.basename(path).casecmp("README.md").zero?
|
|
10
|
+
|
|
11
|
+
title = extract_title(content, path)
|
|
12
|
+
parent = parent_label(path)
|
|
13
|
+
doc_type = root_readme?(path) ? "root_readme" : "readme"
|
|
14
|
+
purpose = if doc_type == "root_readme"
|
|
15
|
+
"Monorepo entry point and navigation for ACE"
|
|
16
|
+
else
|
|
17
|
+
"User-facing introduction for #{parent}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
metadata = {
|
|
21
|
+
"doc-type" => doc_type,
|
|
22
|
+
"purpose" => purpose,
|
|
23
|
+
"update" => {"frequency" => "on-change"}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if last_updated
|
|
27
|
+
metadata["ace-docs"] = {"last-updated" => last_updated.strftime("%Y-%m-%d")}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
metadata["title"] = title
|
|
31
|
+
metadata
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.extract_title(content, path)
|
|
35
|
+
match = content.to_s.match(/^#\s+([^\n]+)$/)
|
|
36
|
+
return match[1].strip if match
|
|
37
|
+
|
|
38
|
+
parent_label(path)
|
|
39
|
+
end
|
|
40
|
+
private_class_method :extract_title
|
|
41
|
+
|
|
42
|
+
def self.parent_label(path)
|
|
43
|
+
parent = File.basename(File.dirname(path.to_s))
|
|
44
|
+
(parent.nil? || parent.empty? || parent == ".") ? File.basename(Dir.pwd) : parent
|
|
45
|
+
end
|
|
46
|
+
private_class_method :parent_label
|
|
47
|
+
|
|
48
|
+
def self.root_readme?(path)
|
|
49
|
+
normalized = path.to_s.sub(%r{\A\./}, "")
|
|
50
|
+
return true if normalized.casecmp("README.md").zero?
|
|
51
|
+
|
|
52
|
+
File.expand_path(path.to_s) == File.join(Dir.pwd, "README.md")
|
|
53
|
+
rescue
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
private_class_method :root_readme?
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|