ai-meta-factory 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,110 @@
1
+ AI META FACTORY NON-COMMERCIAL LICENSE
2
+ Version 1.0 — 2026
3
+
4
+ Copyright (c) 2026 Devendra Solanki
5
+
6
+ 1. Definitions
7
+
8
+ “Software” means the ai-meta-factory source code, documentation,
9
+ prompt files, templates, configuration, and other materials distributed
10
+ with this license.
11
+
12
+ “Commercial Use” means any use of the Software that is intended for or
13
+ directly connected with commercial advantage, monetary compensation,
14
+ revenue generation, business operations, paid services, or economic benefit.
15
+
16
+ Commercial Use includes, without limitation:
17
+
18
+ a. use by a company, business, agency, or other commercial organization;
19
+ b. use in developing, testing, operating, or maintaining a commercial product;
20
+ c. use for internal business, engineering, consulting, or client work;
21
+ d. use in a paid service, hosted service, SaaS product, or managed service;
22
+ e. use in work delivered to a paying customer;
23
+ f. selling, sublicensing, leasing, renting, or redistributing the Software;
24
+ g. embedding the Software into a commercial product or service;
25
+ h. offering support, training, implementation, or other paid services
26
+ substantially based on the Software.
27
+
28
+ “Non-Commercial Use” means personal, educational, academic, research,
29
+ evaluation, or other use that is not Commercial Use.
30
+
31
+ “Licensor” means Devendra Solanki.
32
+
33
+ 2. Permission for Non-Commercial Use
34
+
35
+ Subject to the conditions in this license, the Licensor grants you a
36
+ limited, worldwide, non-exclusive, non-transferable, non-sublicensable,
37
+ royalty-free license to use, copy, modify, and distribute the Software
38
+ solely for Non-Commercial Use.
39
+
40
+ 3. Commercial Use Requires Permission
41
+
42
+ Commercial Use is not permitted under this license.
43
+
44
+ You must obtain a separate written commercial license from the Licensor
45
+ before undertaking any Commercial Use.
46
+
47
+ Commercial licensing inquiries:
48
+
49
+ Email: [YOUR-COMMERCIAL-LICENSE-EMAIL]
50
+ Repository: https://github.com/devendra-solanki-work/ai-meta-factory
51
+
52
+ 4. Distribution Conditions
53
+
54
+ For permitted Non-Commercial Use, you must:
55
+
56
+ a. retain this license notice;
57
+ b. retain the copyright notice;
58
+ c. include a copy of this license with any distribution;
59
+ d. clearly identify modifications made to the Software; and
60
+ e. not represent modified Software as the original Software.
61
+
62
+ You may not sell, sublicense, or commercially redistribute the Software
63
+ or any derivative work under this license.
64
+
65
+ 5. Restrictions
66
+
67
+ You may not:
68
+
69
+ a. use the Software for Commercial Use;
70
+ b. remove or alter copyright, license, or attribution notices;
71
+ c. use the Licensor's name, trademarks, or branding to imply endorsement;
72
+ d. circumvent the commercial licensing requirements of this license; or
73
+ e. distribute the Software in a manner that suggests it is available
74
+ for unrestricted commercial use.
75
+
76
+ 6. No Trademark License
77
+
78
+ This license does not grant permission to use the name, trademarks,
79
+ logos, service marks, or branding of the Licensor or the project,
80
+ except as reasonably necessary to identify the Software.
81
+
82
+ 7. No Warranty
83
+
84
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS
85
+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
86
+ FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
87
+
88
+ 8. Limitation of Liability
89
+
90
+ TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSOR SHALL NOT
91
+ BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING FROM, OUT OF,
92
+ OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
93
+ SOFTWARE.
94
+
95
+ 9. Termination
96
+
97
+ This license terminates automatically if you breach its terms.
98
+
99
+ Upon termination, you must stop using, copying, modifying, and distributing
100
+ the Software, except that permissions granted to recipients who complied
101
+ with this license before termination will not be revoked solely because
102
+ of your breach.
103
+
104
+ 10. Reservation of Rights
105
+
106
+ All rights not expressly granted under this license are reserved by the
107
+ Licensor.
108
+
109
+ This license is not an open-source license because it restricts Commercial
110
+ Use.
package/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # ai-meta-factory
2
+
3
+ **Build consistent repository context for AI agents.**
4
+
5
+ A meta-factory that generates structured project context artifacts from repository scans. These artifacts empower AI agents with accurate, repository-specific guidance, eliminating guesswork and ensuring consistent responses.
6
+
7
+ ## What is this?
8
+
9
+ `ai-meta-factory` is a system for generating and maintaining AI-friendly documentation artifacts. Instead of relying on AI agents to infer your project's structure, conventions, and constraints from raw code, this factory produces standardized, concise reference files that:
10
+
11
+ - **Ground AI agents** in your project's actual architecture
12
+ - **Enforce consistency** across all agent interactions
13
+ - **Reduce hallucination** by providing authoritative facts
14
+ - **Speed up onboarding** for new developers and AI assistants
15
+
16
+ ## How it works
17
+
18
+ The factory operates in stages:
19
+
20
+ 1. **Scanner** (`meta/factory/scanner.prompt`)
21
+ - Analyzes repository structure, languages, frameworks, and conventions
22
+ - Produces `repo-context.yaml` — the master source of truth
23
+
24
+ 2. **Context Generator** (`meta/factory/000-context-generator.prompt`)
25
+ - Transforms scanner output into `.cursor/rules/000-project-context.mdc`
26
+ - Compact lookup table: stack, entry points, directories, constraints, naming conventions
27
+
28
+ 3. **Architecture Documenter** (`meta/factory/architecture.prompt`)
29
+ - Generates `.cursor/rules/200-architecture.mdc` — module boundaries and dependency rules
30
+ - Produces `docs/adr/ADR-000-initial-architecture.md` — architecture decisions
31
+
32
+ 4. **Standards & Tests** (`meta/factory/standards.prompt`, `tests.prompt`)
33
+ - Coding standards: `.cursor/rules/100-*-standards.mdc`
34
+ - Test conventions: `.cursor/rules/300-test-conventions.mdc`
35
+
36
+ 5. **Drift Check** (`meta/factory/drift-check.prompt`)
37
+ - Validates that actual codebase matches generated context
38
+ - Flags architectural violations and outdated documentation
39
+
40
+ 6. **Claude Markdown** (`meta/factory/claudemd.prompt`)
41
+ - Generates `.cursor/rules/900-claude-instructions.mdc`
42
+ - Custom behavioral rules and tone guidance for AI assistants
43
+
44
+ ## Output artifacts
45
+
46
+ All generated files live in `.cursor/rules/` and `docs/` — optimized for AI context windows:
47
+
48
+ | Artifact | Purpose | Lines |
49
+ |----------|---------|-------|
50
+ | `000-project-context.mdc` | Quick reference (stack, entry points, directories) | ≤50 |
51
+ | `100-*-standards.mdc` | Coding standards & conventions | Modular |
52
+ | `200-architecture.mdc` | Module map, dependency rules, constraints | ≤30 |
53
+ | `300-test-conventions.mdc` | Testing patterns and requirements | Concise |
54
+ | `900-claude-instructions.mdc` | Custom AI behavior and tone | Brief |
55
+ | `docs/adr/ADR-*.md` | Architecture Decision Records | Linked |
56
+
57
+ ## Core principles
58
+
59
+ 1. **Terse over friendly** — Every token matters in an AI context window
60
+ 2. **Facts over prose** — Lookup tables, not essays
61
+ 3. **Observable evidence** — All patterns backed by real code
62
+ 4. **Sanctioned constraints** — Only document things that break if violated
63
+ 5. **Single source of truth** — Scanner output is canonical
64
+
65
+ ## Design philosophy
66
+
67
+ This factory treats AI agents as first-class participants in development:
68
+
69
+ - **Agents need context, not tutorials** — No "here's what TypeScript is"
70
+ - **Agents need boundaries, not guidelines** — Hard rules, not best practices
71
+ - **Agents need signals, not noise** — Facts compressed to essentials
72
+ - **Agents need consistency** — One source of truth for all interactions
73
+
74
+ ## Who is this for?
75
+
76
+ - **Teams using AI coding agents** (GitHub Copilot, Claude, etc.)
77
+ - **Projects that want consistent AI-assisted development**
78
+ - **Organizations scaling AI-driven workflows** across multiple repositories
79
+
80
+ ## Implementation
81
+
82
+ See [`artifact-factory-team-runbook.docx`](artifact-factory-team-runbook.docx) for detailed implementation guides and team workflows.
83
+
84
+ ## Getting started
85
+
86
+ 1. Run the scanner prompt on your repository
87
+ 2. Generate initial artifacts using factory prompts
88
+ 3. Integrate `.cursor/rules/` into your Cursor/IDE configuration
89
+ 4. Run periodic drift checks to keep context fresh
90
+
91
+ ## License
92
+
93
+ The project is available under the
94
+ [AI Meta Factory Non-Commercial License](LICENSE).
95
+
96
+ Personal, educational, academic, research, and evaluation use is permitted
97
+ subject to the license terms.
98
+
99
+ Commercial use requires a separate written commercial license.
100
+
101
+ For commercial licensing inquiries, contact:
102
+
103
+ `[devendra.solanki.work@gmail.com]`
104
+
105
+ ---
106
+
107
+ **License:** See repository for license information
108
+ **Status:** Active development
@@ -0,0 +1,3 @@
1
+ import type { RepoContext, RenderedFile, Target } from './types.js';
2
+ export declare function render(context: RepoContext, target: Exclude<Target, 'all'>): RenderedFile[];
3
+ export declare function targets(value: Target): Exclude<Target, 'all'>[];
@@ -0,0 +1,51 @@
1
+ import { createHash } from 'node:crypto';
2
+ const yaml = (context) => `repository:\n name: ${context.repository.name}\n primary_language: ${context.repository.primaryLanguage ?? 'null'}\n languages: [${context.repository.languages.join(', ')}]\nstack:\n runtime: ${context.stack.runtime ?? 'null'}\n frameworks: [${context.stack.frameworks.join(', ')}]\nstructure:\n directories: [${context.structure.directories.join(', ')}]\n entry_points: [${context.structure.entryPoints.join(', ')}]\ncommands:\n build: ${context.commands.build ?? 'null'}\n test: ${context.commands.test ?? 'null'}\n dev: ${context.commands.dev ?? 'null'}\nconstraints:\n${context.constraints.map((x) => ` - ${x}`).join('\n')}\n`;
3
+ const json = (context) => JSON.stringify({
4
+ ...context,
5
+ systemPrompt: `You are an evidence-driven assistant for ${context.repository.name}. Follow the repository constraints and do not invent missing facts.`
6
+ }, null, 2) + '\n';
7
+ const marker = (context) => createHash('sha256').update(JSON.stringify(context)).digest('hex').slice(0, 12);
8
+ export function render(context, target) {
9
+ const hash = marker(context);
10
+ const header = `<!-- Generated by ai-meta-factory; context ${hash}. Do not edit manually. -->\n`;
11
+ const summary = `# ${context.repository.name} — Project Context\n\n- Languages: ${context.repository.languages.join(', ') || 'unknown'}\n- Runtime: ${context.stack.runtime ?? 'unknown'}\n- Frameworks: ${context.stack.frameworks.join(', ') || 'none detected'}\n- Entry points: ${context.structure.entryPoints.join(', ') || 'none detected'}\n- Directories: ${context.structure.directories.join(', ') || 'none detected'}\n- Constraints: ${context.constraints.join(' ')}\n`;
12
+ switch (target) {
13
+ case 'cursor':
14
+ return [
15
+ {
16
+ path: '.cursor/rules/000-project-context.mdc',
17
+ content: `---\nalwaysApply: true\nname: "000-project-context"\ndescription: "Generated repository reference"\n---\n${header}${summary}`
18
+ },
19
+ { path: 'meta/factory/repo-context.yaml', content: yaml(context) }
20
+ ];
21
+ case 'github-copilot':
22
+ return [
23
+ {
24
+ path: '.github/copilot-instructions.md',
25
+ content: `${header}${summary}\nUse the existing project structure and commands. Do not infer undocumented architecture.`
26
+ },
27
+ { path: 'meta/factory/repo-context.yaml', content: yaml(context) }
28
+ ];
29
+ case 'claude':
30
+ return [
31
+ {
32
+ path: 'CLAUDE.md',
33
+ content: `${header}${summary}\n## Reasoning rules\nUse only observable repository evidence. Preserve architectural boundaries and ask before changing generated context.\n`
34
+ },
35
+ { path: 'meta/factory/repo-context.yaml', content: yaml(context) }
36
+ ];
37
+ case 'gemini':
38
+ return [
39
+ { path: 'gemini-context.json', content: json(context) },
40
+ { path: 'meta/factory/repo-context.yaml', content: yaml(context) }
41
+ ];
42
+ case 'generic':
43
+ return [
44
+ { path: '.ai-context/repo-context.json', content: json(context) },
45
+ { path: '.ai-context/README.md', content: `${header}This directory contains generated, tool-neutral repository context. Regenerate after structural changes.\n` }
46
+ ];
47
+ }
48
+ }
49
+ export function targets(value) {
50
+ return value === 'all' ? ['cursor', 'github-copilot', 'claude', 'gemini', 'generic'] : [value];
51
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { join, resolve } from 'node:path';
4
+ import { render, targets } from './adapters.js';
5
+ import { scan } from './scanner.js';
6
+ const args = process.argv.slice(2);
7
+ const command = args[0] ?? 'init';
8
+ const targetIndex = args.indexOf('--target');
9
+ const target = (targetIndex >= 0 ? args[targetIndex + 1] : 'all');
10
+ const pathIndex = args.indexOf('--path');
11
+ const root = resolve(pathIndex >= 0 ? args[pathIndex + 1] : '.');
12
+ const dryRun = args.includes('--dry-run');
13
+ const force = args.includes('--force');
14
+ if (!['init', 'generate', 'drift-check'].includes(command)) {
15
+ console.error('Usage: ai-meta-factory init|generate|drift-check [--target target] [--dry-run] [--force]');
16
+ process.exit(1);
17
+ }
18
+ const context = scan(root);
19
+ if (command === 'drift-check') {
20
+ const generated = render(context, 'generic').find((file) => file.path === '.ai-context/repo-context.json');
21
+ const actualPath = join(root, '.ai-context/repo-context.json');
22
+ const drifted = !existsSync(actualPath) || readFileSync(actualPath, 'utf8') !== generated?.content;
23
+ console.log(drifted ? 'DRIFT: generated context is missing or outdated.' : 'OK: generated context matches the repository scan.');
24
+ process.exit(drifted ? 2 : 0);
25
+ }
26
+ for (const selected of targets(target)) {
27
+ for (const file of render(context, selected)) {
28
+ const destination = join(root, file.path);
29
+ const directory = destination.slice(0, destination.lastIndexOf('/'));
30
+ if (existsSync(destination) && !force) {
31
+ console.log(`SKIP ${file.path} (exists; use --force to replace)`);
32
+ continue;
33
+ }
34
+ if (dryRun) {
35
+ console.log(`WOULD WRITE ${file.path}`);
36
+ continue;
37
+ }
38
+ mkdirSync(directory, { recursive: true });
39
+ writeFileSync(destination, file.content);
40
+ console.log(`WRITE ${file.path}`);
41
+ }
42
+ }
@@ -0,0 +1,3 @@
1
+ export { scan } from './scanner.js';
2
+ export { render, targets } from './adapters.js';
3
+ export type { RepoContext, RenderedFile, Target } from './types.js';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { scan } from './scanner.js';
2
+ export { render, targets } from './adapters.js';
@@ -0,0 +1,2 @@
1
+ import type { RepoContext } from './types.js';
2
+ export declare function scan(root: string): RepoContext;
@@ -0,0 +1,107 @@
1
+ import { readdirSync, readFileSync, statSync } from 'node:fs';
2
+ import { join, relative } from 'node:path';
3
+ const ignored = new Set(['.git', 'node_modules', 'dist', 'build', 'coverage', '.next', '.venv']);
4
+ function packageJson(root) {
5
+ try {
6
+ return JSON.parse(readFileSync(join(root, 'package.json'), 'utf8'));
7
+ }
8
+ catch {
9
+ return {};
10
+ }
11
+ }
12
+ function files(root, depth = 0) {
13
+ if (depth > 4)
14
+ return [];
15
+ const result = [];
16
+ for (const entry of readdirSync(root)) {
17
+ if (ignored.has(entry))
18
+ continue;
19
+ const absolute = join(root, entry);
20
+ const stat = statSync(absolute);
21
+ if (stat.isDirectory()) {
22
+ result.push(...files(absolute, depth + 1));
23
+ }
24
+ else {
25
+ result.push(relative(process.cwd(), absolute).replaceAll('\\', '/'));
26
+ }
27
+ }
28
+ return result;
29
+ }
30
+ function read(root, name) {
31
+ try {
32
+ return readFileSync(join(root, name), 'utf8');
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ function detectLanguage(paths) {
39
+ const map = {
40
+ '.ts': 'TypeScript',
41
+ '.tsx': 'TypeScript',
42
+ '.js': 'JavaScript',
43
+ '.jsx': 'JavaScript',
44
+ '.py': 'Python',
45
+ '.go': 'Go',
46
+ '.rs': 'Rust',
47
+ '.java': 'Java',
48
+ '.cs': 'C#',
49
+ '.rb': 'Ruby'
50
+ };
51
+ const result = new Set();
52
+ for (const path of paths) {
53
+ const ext = path.includes('.') ? path.slice(path.lastIndexOf('.')) : '';
54
+ const detected = map[ext];
55
+ if (detected)
56
+ result.add(detected);
57
+ }
58
+ return [...result].sort();
59
+ }
60
+ export function scan(root) {
61
+ const paths = files(root);
62
+ const pkg = packageJson(root);
63
+ const languages = detectLanguage(paths);
64
+ const dirs = [...new Set(paths.map((p) => p.split('/')[0]).filter((p) => !p.includes('.') && p.length > 0))].sort();
65
+ const entryPoints = paths.filter((p) => /(^|\/)(index|main|app|server)\.(ts|tsx|js|jsx|py|go|rs)$/.test(p)).slice(0, 10);
66
+ const scripts = pkg.scripts ?? {};
67
+ const frameworks = [
68
+ ...(pkg.dependencies ? Object.keys(pkg.dependencies).filter((name) => ['react', 'next', 'express', 'fastify', 'nestjs', 'vue', 'angular'].some((token) => name.includes(token))) : []),
69
+ ...(read(root, 'pyproject.toml')?.match(/(?:django|fastapi|flask|pytest)/gi) ?? [])
70
+ ];
71
+ const testFiles = paths.filter((p) => /(test|spec)\.(ts|tsx|js|jsx|py|go)$/.test(p));
72
+ const packageManager = pkg.packageManager ?? (read(root, 'package-lock.json') ? 'npm' :
73
+ read(root, 'pnpm-lock.yaml') ? 'pnpm' :
74
+ read(root, 'yarn.lock') ? 'yarn' :
75
+ null);
76
+ return {
77
+ repository: {
78
+ name: pkg.name ?? root.split('/').pop() ?? 'repository',
79
+ description: pkg.description ?? null,
80
+ primaryLanguage: languages[0] ?? null,
81
+ languages
82
+ },
83
+ stack: {
84
+ frameworks: [...new Set(frameworks)].sort(),
85
+ packageManager,
86
+ runtime: languages.includes('TypeScript') || languages.includes('JavaScript') ? 'Node.js' : null
87
+ },
88
+ structure: {
89
+ directories: dirs,
90
+ entryPoints
91
+ },
92
+ conventions: {
93
+ files: languages.length ? 'Observe existing file naming and preserve repository conventions.' : null,
94
+ tests: testFiles.length ? `${testFiles.length} test-like files detected.` : null
95
+ },
96
+ commands: {
97
+ build: scripts.build ?? null,
98
+ test: scripts.test ?? null,
99
+ dev: scripts.dev ?? scripts.start ?? null
100
+ },
101
+ constraints: [
102
+ 'Generated artifacts must remain evidence-backed.',
103
+ 'Do not overwrite user-authored files without explicit confirmation.'
104
+ ],
105
+ generatedAt: new Date().toISOString()
106
+ };
107
+ }
@@ -0,0 +1,33 @@
1
+ export type Target = 'cursor' | 'github-copilot' | 'claude' | 'gemini' | 'generic' | 'all';
2
+ export interface RepoContext {
3
+ repository: {
4
+ name: string;
5
+ description: string | null;
6
+ primaryLanguage: string | null;
7
+ languages: string[];
8
+ };
9
+ stack: {
10
+ frameworks: string[];
11
+ packageManager: string | null;
12
+ runtime: string | null;
13
+ };
14
+ structure: {
15
+ directories: string[];
16
+ entryPoints: string[];
17
+ };
18
+ conventions: {
19
+ files: string | null;
20
+ tests: string | null;
21
+ };
22
+ commands: {
23
+ build: string | null;
24
+ test: string | null;
25
+ dev: string | null;
26
+ };
27
+ constraints: string[];
28
+ generatedAt: string;
29
+ }
30
+ export interface RenderedFile {
31
+ path: string;
32
+ content: string;
33
+ }
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "ai-meta-factory",
3
+ "version": "0.1.0",
4
+ "description": "Repository-aware context generator for AI coding tools.",
5
+ "keywords": [
6
+ "ai",
7
+ "coding-agents",
8
+ "repository-context",
9
+ "developer-tools",
10
+ "artificial-intelligence"
11
+ ],
12
+ "author": "Devendra Solanki",
13
+ "homepage": "https://github.com/devendra-solanki-work/ai-meta-factory",
14
+ "type": "module",
15
+ "bin": {
16
+ "ai-meta-factory": "dist/cli.js"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/devendra-solanki-work/ai-meta-factory.git"
21
+ },
22
+ "exports": {
23
+ ".": "./dist/index.js"
24
+ },
25
+ "files": [
26
+ "dist",
27
+ "README.md",
28
+ "LICENSE"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsc",
32
+ "start": "node dist/cli.js",
33
+ "check": "tsc --noEmit"
34
+ },
35
+ "engines": {
36
+ "node": ">=18"
37
+ },
38
+ "devDependencies": {
39
+ "@types/node": "^22.10.2",
40
+ "typescript": "^5.7.2"
41
+ },
42
+ "license": "SEE LICENSE IN LICENSE"
43
+ }