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
16 changes: 9 additions & 7 deletions AI.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,23 @@ Key files you'll work with:

* `information-dense-keywords.md` - The core dictionary content
* `README.md` - Project documentation and usage guide
* `docs/roadmaps/ROADMAP.md` - Development priorities and future plans
* `docs/roadmaps/` - Directory for roadmap documents (e.g., `q4-roadmap.md`)
* `docs/plans/` - Directory for planning documents (e.g., `new-feature-plan.md`)
* `docs/specs/` - Directory for specifications (e.g., `api-spec-v2.md`)
* `docs/research/` - Directory for research notes (e.g., `competitor-analysis.md`)
* `examples/` - Usage examples and guides
* `adrs/` - Architecture decision records
* `AI.md` - This shared AI instruction file
* `CLAUDE.md` - Claude-specific instructions
* `GEMINI.md` - Gemini-specific instructions

## Cross-References

* [information-dense-keywords.md](information-dense-keywords.md) - The core command dictionary
* [README.md](README.md) - Main project documentation
* [docs/roadmaps/ROADMAP.md](docs/roadmaps/ROADMAP.md) - Development roadmap and priorities
* [docs/roadmaps/](docs/roadmaps/) - Directory for roadmap documents
* [docs/plans/](docs/plans/) - Directory for planning documents
* [docs/specs/](docs/specs/) - Directory for specifications
* [docs/research/](docs/research/) - Directory for research notes
* [examples/ai-usage-guide.md](examples/ai-usage-guide.md) - AI usage examples
* [CLAUDE.md](CLAUDE.md) - Claude-specific context and instructions
* [GEMINI.md](GEMINI.md) - Gemini-specific context and instructions

## Core Principles

Expand All @@ -80,4 +82,4 @@ Remember: This project focuses on creating a clear, actionable vocabulary for hu

## AI-Specific Considerations

Each AI assistant should reference this file for common guidance, then refer to their specific instruction file (CLAUDE.md, GEMINI.md, etc.) for platform-specific considerations and capabilities.
Each AI assistant should reference this file for common guidance, then refer to their specific instruction file for platform-specific considerations and capabilities.
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ This file provides Claude-specific guidance when working with the Information De

- [AI.md](AI.md) - Shared instructions for all AI assistants
- [information-dense-keywords.md](information-dense-keywords.md) - The core command dictionary
- [docs/roadmaps/ROADMAP.md](docs/roadmaps/ROADMAP.md) - Development roadmap and priorities
- [docs/roadmaps/](docs/roadmaps/) - Development roadmap and priorities
- [GEMINI.md](GEMINI.md) - Gemini-specific context and instructions
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ The core dictionary is in [`information-dense-keywords.md`](information-dense-ke

### 3. AI Instructions

- [`AI.md`](AI.md) contains shared instructions for all AI assistants
- [`CLAUDE.md`](CLAUDE.md) and [`GEMINI.md`](GEMINI.md) contain model-specific guidance
- Update these files when dictionary changes affect AI behavior
- [`AI.md`](AI.md) contains shared instructions for all AI assistants.
- For model-specific guidance, follow the pattern of `CLAUDE.md` and `GEMINI.md`.
- Update these files when dictionary changes affect AI behavior.

## 🔧 Development Workflow

Expand Down Expand Up @@ -107,7 +107,7 @@ Good command definition:
## 📚 Resources

- [AI Usage Guide](examples/ai-usage-guide.md) - How AIs should use the dictionary
- [Project Roadmap](docs/roadmaps/ROADMAP.md) - Future development plans
- [Project Roadmap](docs/roadmaps/) - Future development plans
- [ADRs](adrs/) - Architectural decision records

## 📄 License
Expand Down
2 changes: 1 addition & 1 deletion GEMINI.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ This file provides Gemini-specific guidance when working with the Information De

- [AI.md](AI.md) - Shared instructions for all AI assistants
- [information-dense-keywords.md](information-dense-keywords.md) - The core command dictionary
- [docs/roadmaps/ROADMAP.md](docs/roadmaps/ROADMAP.md) - Development roadmap and priorities
- [docs/roadmaps/](docs/roadmaps/) - Development roadmap and priorities
- [CLAUDE.md](CLAUDE.md) - Claude-specific context and instructions
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
- [AI Usage Guide](examples/ai-usage-guide.md) - Detailed implementation guidance
- [Command Definitions](information-dense-keywords.md) - Complete command index
- [Architecture Decision Records](adrs/) - Design decisions and evolution
- [Roadmap](docs/roadmaps/ROADMAP.md) - Future development plans
- [Roadmap](docs/roadmaps/) - Future development plans

*Note: Links to `docs/roadmaps/`, `docs/plans/`, etc., are conventions for AI assistants. These directories do not exist in the source repository but should be created in your local project clone.*

## 📄 License

Expand Down
5 changes: 3 additions & 2 deletions tests/dictionary-validator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const { shouldSkipLink } = require('./lib/link-helper');

class DictionaryValidator {
constructor() {
Expand Down Expand Up @@ -138,8 +139,8 @@ class DictionaryValidator {
while ((match = linkPattern.exec(content)) !== null) {
const [, linkText, linkPath] = match;

// Skip external links
if (linkPath.startsWith('http://') || linkPath.startsWith('https://')) {
// Skip external links and conceptual docs links, as they are not expected to exist in the repo.
if (shouldSkipLink(linkPath)) {
continue;
}

Expand Down
18 changes: 18 additions & 0 deletions tests/lib/link-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Checks if a given link path should be skipped during validation.
*
* @param {string} linkPath - The path of the link to check.
* @returns {boolean} - True if the link should be skipped, false otherwise.
*/
function shouldSkipLink(linkPath) {
// Skip external links (http/https) and conceptual 'docs/' links.
// The 'docs/' directory is a convention for AI-generated content in the user's
// project and is not expected to exist in this source repository.
return (
linkPath.startsWith('http://') ||
linkPath.startsWith('https://') ||
linkPath.startsWith('docs/')
);
}

module.exports = { shouldSkipLink };
58 changes: 19 additions & 39 deletions tests/link-validation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const { shouldSkipLink } = require('./lib/link-helper');

class LinkValidationTest {
constructor() {
Expand Down Expand Up @@ -140,10 +141,16 @@ class LinkValidationTest {
relativeLinks.forEach(link => {
this.test(`${fileName}: relative link "${link.text}" -> ${link.path}`, () => {
const filePath = path.join(this.rootDir, file);
// The link resolution test should not apply to conceptual directories or external URLs.
if (shouldSkipLink(link.path)) {
return; // Skip validation for these paths
}

const resolvedPath = path.resolve(path.dirname(filePath), link.path);

// fs.existsSync works for both files and directories.
if (!fs.existsSync(resolvedPath)) {
throw new Error(`Broken relative link: ${link.path} (line ${link.lineNumber})`);
throw new Error(`Broken relative link: target does not exist at ${link.path} (line ${link.lineNumber})`);
}
});
});
Expand All @@ -153,47 +160,20 @@ class LinkValidationTest {
testCrossReferences() {
console.log('🔗 Testing cross-references...');

const commandFiles = Array.from(this.linkMap.keys()).filter(file =>
file.startsWith('dictionary/') && file.endsWith('.md')
);

// Build command name index
const commandIndex = new Map();
commandFiles.forEach(file => {
const filePath = path.join(this.rootDir, file);
const content = fs.readFileSync(filePath, 'utf8');
const h1Match = content.match(/^# (.+)/m);

if (h1Match) {
commandIndex.set(h1Match[1].trim().toLowerCase(), file);
}
});

// Test that referenced commands exist
commandFiles.forEach(file => {
const links = this.linkMap.get(file) || [];
this.linkMap.forEach((links, file) => {
const fileName = path.basename(file);

const commandLinks = links.filter(link =>
link.path.includes('dictionary/') || link.text.includes('**')
);
links.forEach(link => {
this.test(`${fileName}: cross-reference "${link.text}" -> ${link.path} is valid`, () => {
// Skip external links and conceptual docs links, as they are not expected to exist in the repo.
if (shouldSkipLink(link.path)) {
return;
}

const targetPath = path.resolve(path.dirname(path.join(this.rootDir, file)), link.path);

commandLinks.forEach(link => {
this.test(`${fileName}: cross-reference "${link.text}" is valid`, () => {
if (link.path.startsWith('dictionary/') || link.path.startsWith('../')) {
// It's a dictionary reference
const normalizedText = link.text.replace(/\*\*/g, '').toLowerCase();

if (!commandIndex.has(normalizedText) && !fs.existsSync(path.join(this.rootDir, link.path))) {
// More flexible check - see if it exists as a file
const targetPath = link.path.startsWith('../')
? path.resolve(path.dirname(path.join(this.rootDir, file)), link.path)
: path.join(this.rootDir, link.path);

if (!fs.existsSync(targetPath)) {
throw new Error(`Cross-reference target not found: ${link.path}`);
}
}
if (!fs.existsSync(targetPath)) {
throw new Error(`Broken link: target does not exist at ${link.path} (line ${link.lineNumber})`);
}
});
});
Expand Down