Skip to content

feat: add skillkit primer command for AI instruction generation#25

Merged
rohitg00 merged 4 commits into
mainfrom
feat/skillkit-primer
Jan 29, 2026
Merged

feat: add skillkit primer command for AI instruction generation#25
rohitg00 merged 4 commits into
mainfrom
feat/skillkit-primer

Conversation

@rohitg00

@rohitg00 rohitg00 commented Jan 29, 2026

Copy link
Copy Markdown
Owner

Summary

New feature that analyzes codebases and generates AI instruction files for all 32 supported agents, inspired by pierceboggan/primer.

New Module: packages/core/src/primer/

  • types.ts: Zod schemas and TypeScript interfaces
  • analyzer.ts: Codebase analysis (languages, frameworks, conventions)
  • generator.ts: Agent-specific instruction file generation
  • __tests__/primer.test.ts: 15 comprehensive tests

CLI Command: skillkit primer

skillkit primer                    # Analyze current dir, generate for detected agents
skillkit primer --all-agents       # Generate for all 32 agents
skillkit primer --agent claude-code,cursor  # Specific agents only
skillkit primer --output ./instructions     # Custom output directory
skillkit primer --dry-run          # Show what would be generated
skillkit primer --analyze-only     # Only show analysis, don't generate
skillkit primer --json             # JSON output for analysis

Analysis Features

  • Languages: TypeScript, JavaScript, Python, Go, Rust, Java, etc.
  • Frameworks: React, Next.js, Express, FastAPI, Django, etc.
  • Package Managers: npm, pnpm, yarn, pip, cargo, go modules
  • Code Conventions: Indentation, quotes, semicolons
  • Project Structure: Monorepo, src-based, flat
  • CI/CD: GitHub Actions, GitLab CI, CircleCI
  • Docker: Dockerfile detection

Generated Files

Creates agent-specific instruction files:

  • CLAUDE.md for Claude Code
  • .cursorrules for Cursor
  • .github/copilot-instructions.md for GitHub Copilot
  • .gemini/settings.json for Gemini CLI
  • And more for all 32 agents...

Test plan

  • 15 new tests for primer module
  • All 694 core tests pass
  • Build succeeds

Open with Devin

Summary by CodeRabbit

  • New Features

    • Adds a new "primer" CLI command to analyze projects and generate AI instruction files for supported agents (all or specific), with dry-run, analyze-only, JSON output, examples, and custom output directory.
    • Introduces project analysis and instruction generation capabilities (multi-agent, per-agent outputs, multiple formats).
  • Documentation

    • New "AI Instruction Generation (Primer)" README section with usage examples and CLI reference, plus a "Custom AI Sub-Agents" subsection.
  • Public API

    • Primer analysis and generation surfaces added to the public API.
  • Tests

    • New test suite validating analysis and generation workflows, detections, and dry-run behavior.

✏️ Tip: You can customize this high-level summary in your review settings.

New feature that analyzes codebases and generates AI instruction files
for all 32 supported agents (inspired by pierceboggan/primer).

## New Module: packages/core/src/primer/
- types.ts: Zod schemas and TypeScript interfaces
- analyzer.ts: Codebase analysis (languages, frameworks, conventions)
- generator.ts: Agent-specific instruction file generation
- index.ts: Barrel exports
- __tests__/primer.test.ts: 15 comprehensive tests

## CLI Command: skillkit primer
- --agent/-a: Generate for specific agents
- --all-agents/-A: Generate for all 32 agents
- --output/-o: Custom output directory
- --dry-run/-n: Preview without writing
- --analyze-only: Show analysis only
- --verbose/-v: Detailed output
- --json/-j: JSON output

## Features
- Detects: languages, frameworks, package managers, libraries
- Analyzes: project structure, code conventions, CI/CD, Docker
- Generates: CLAUDE.md, .cursorrules, copilot-instructions.md, etc.
@vercel

vercel Bot commented Jan 29, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
skillkit Ready Ready Preview, Comment Jan 29, 2026 7:09pm
skillkit-docs Ready Ready Preview, Comment Jan 29, 2026 7:09pm

@coderabbitai

coderabbitai Bot commented Jan 29, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

Adds a new Primer subsystem: static project analysis and per-agent AI instruction generation, a CLI primer command wiring that invokes analysis/generation (supports dry-run and analyze-only), new types, tests, and exposes the primer API from core and CLI bundles.

Changes

Cohort / File(s) Summary
Documentation
README.md
Adds "AI Instruction Generation (Primer)" docs, CLI examples, usage flags, and "Custom AI Sub-Agents" subsection.
CLI Integration
apps/skillkit/src/cli.ts, packages/cli/src/commands/index.ts
Registers PrimerCommand with the CLI and re-exports it from commands barrel.
CLI Command Implementation
packages/cli/src/commands/primer.ts
New PrimerCommand class with options for agent selection, all-agents, output dir, dry-run, analyze-only, json/verbose, examples; execution branches into analysis or generation flows and prints results.
Core Barrel Export
packages/core/src/index.ts, packages/core/src/primer/index.ts
Re-exports the primer module from core, exposing analyzer/generator/types in the public API.
Types & Templates
packages/core/src/primer/types.ts
New Zod schemas, enums, and exported TS types/interfaces (PrimerAnalysis, PrimerOptions, GeneratedInstruction, PrimerResult, AgentInstructionTemplate, AGENT_INSTRUCTION_TEMPLATES).
Project Analyzer
packages/core/src/primer/analyzer.ts
New PrimerAnalyzer and analyzePrimer() implementing static repo inspection (metadata, languages, package manager, frameworks, styling, testing, CI/CD, env, Docker, build commands, conventions, structure).
Content Generator
packages/core/src/primer/generator.ts
New PrimerGenerator, helper functions (generatePrimer, generatePrimerForAgent, analyzeForPrimer), renderers (md/json/xml), per-agent instruction assembly, dry-run/analyze-only handling, IO, warnings/errors aggregation.
Tests
packages/core/src/primer/__tests__/primer.test.ts
Comprehensive tests for analyzer and generator: detection assertions, dry-run behavior, per-agent generation, analyze-only mode, and output placement.

Sequence Diagram(s)

sequenceDiagram
    participant CLI as PrimerCommand (CLI)
    participant Analyzer as PrimerAnalyzer
    participant Generator as PrimerGenerator
    participant FS as File System

    CLI->>Analyzer: analyzePrimer(projectPath)
    activate Analyzer
    Analyzer->>FS: scan files & configs
    FS-->>Analyzer: metadata & artifacts
    Analyzer-->>CLI: PrimerAnalysis
    deactivate Analyzer

    alt analyze-only
        CLI->>CLI: print analysis
    else generate
        CLI->>Generator: generatePrimer(projectPath, agents, options)
        activate Generator
        Generator->>Generator: determine target agents
        loop per agent
            Generator->>Generator: build content sections (overview, stack, commands, conventions, structure, guidelines)
            alt not dry-run
                Generator->>FS: write instruction file(s)
                FS-->>Generator: write results
            end
        end
        Generator-->>CLI: PrimerResult (generated files, warnings, errors)
        deactivate Generator
        CLI->>CLI: print summary
    end
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

🐰 I hopped through folders, sniffed the stack and tree,
Wove agent notes for thirty-two (or maybe three).
I packaged guidance, tests snug in a bun,
Dry-run, analyze — now go have some fun!
Hop on, tiny coder — your primer is done.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add skillkit primer command for AI instruction generation' clearly summarizes the main feature addition—a new CLI command for generating AI instructions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View issue and 5 additional flags in Devin Review.

Open in Devin Review

if ('semi' in config) conventions.semicolons = config.semi;
if ('singleQuote' in config) conventions.quotes = config.singleQuote ? 'single' : 'double';
if ('tabWidth' in config) {
conventions.indentation = config.useTabs ? 'tabs' : `spaces-${config.tabWidth}` as 'spaces-2' | 'spaces-4';

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Invalid indentation value created when tabWidth is not 2 or 4

When parsing Prettier configuration, the code constructs an indentation value using string interpolation spaces-${config.tabWidth}, but the Zod schema at types.ts:43 only allows 'tabs' | 'spaces-2' | 'spaces-4'.

Click to expand

Issue

If a project has a Prettier config with tabWidth: 3, tabWidth: 8, or any value other than 2 or 4, the code will create an invalid value like 'spaces-8' or 'spaces-3'.

Code at analyzer.ts:380-382:

if ('tabWidth' in config) {
  conventions.indentation = config.useTabs ? 'tabs' : `spaces-${config.tabWidth}` as 'spaces-2' | 'spaces-4';
}

Expected behavior

The code should validate that tabWidth is 2 or 4 before assigning, or map other values to the closest valid option.

Impact

This creates a type mismatch where the runtime value doesn't match the declared TypeScript type. While TypeScript won't catch this at compile time due to the as assertion, it could cause issues if the value is validated against the Zod schema or if downstream code expects only the valid enum values.

Recommendation: Validate tabWidth before assignment: conventions.indentation = config.useTabs ? 'tabs' : (config.tabWidth === 4 ? 'spaces-4' : 'spaces-2');

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In `@packages/core/src/primer/analyzer.ts`:
- Around line 1-3: relativePath is built using a hardcoded '/' replace and
directory counts check for '/' which breaks on Windows; update all occurrences
(the relativePath calculation and the directory-counting logic referenced around
lines 122-141 and 580-594) to use path.relative(...) to compute the path and use
path.sep (or split by path.sep) for any directory boundary checks/counts so
backslashes are normalized across OSes; replace manual string replace operations
that force '/' with these platform-safe utilities (refer to the variable name
relativePath and the directory-counting logic where split or indexOf('/') is
used).

In `@packages/core/src/primer/generator.ts`:
- Around line 60-92: The loop in generate() can overwrite outputs when multiple
agents produce the same filename (e.g., AGENTS.md); modify generate() to detect
duplicate output paths before writing by collecting each agent's intended output
path (use generateForAgent() to obtain the instruction.path or equivalent) and
checking against a set; on collision, either log a warning and skip writing for
the later agent (push a warning into warnings and an error into errors if
desired) or disambiguate the path (e.g., append agent name) before calling
writeInstruction(); ensure this check runs regardless of options.dryRun so
generated still reflects what would be produced and update
getTargetAgents()/generated/writeInstruction() usage accordingly.

In `@README.md`:
- Around line 316-326: Update the README's "AI Instruction Generation (Primer)"
examples to include usage examples for the missing CLI flags --output and --json
(alongside existing commands like "skillkit primer" and "skillkit primer
--all-agents"), e.g., show one example that writes generated primers to a
directory using --output <dir> and another that emits machine-readable output
using --json (optionally combined with --dry-run or --agent), ensuring the new
examples mention the exact flags (--output, --json) so users can discover them.
🧹 Nitpick comments (4)
packages/core/src/primer/types.ts (1)

93-95: Use the PackageManager enum in PrimerAnalysis

packageManagers currently accepts arbitrary strings even though PackageManager is defined. Using the enum keeps validation and downstream assumptions aligned.

♻️ Suggested change
-  packageManagers: z.array(z.string()).default([]),
+  packageManagers: z.array(PackageManager).default([]),
packages/core/src/primer/analyzer.ts (1)

319-329: Detect monorepos before src‑based layout

If src/ co-exists with packages/ or apps/, the current order labels the repo as src-based, which can misclassify monorepos that don’t use workspaces. Consider checking monorepo markers first.

♻️ Suggested change
-    if (this.hasFile('src')) {
-      structure.type = 'src-based';
-      structure.srcDir = 'src';
-    } else if (this.hasFile('packages') || this.hasFile('apps')) {
-      structure.type = 'monorepo';
-    } else if (this.hasFile('lib')) {
+    if (this.hasFile('packages') || this.hasFile('apps')) {
+      structure.type = 'monorepo';
+    } else if (this.hasFile('src')) {
+      structure.type = 'src-based';
+      structure.srcDir = 'src';
+    } else if (this.hasFile('lib')) {
       structure.type = 'src-based';
       structure.srcDir = 'lib';
     } else {
packages/core/src/primer/__tests__/primer.test.ts (1)

169-182: Add defensive check before accessing the first generated element.

Line 176 accesses result.generated[0] directly after asserting the operation succeeded. If the generator behavior changes and returns an empty array despite success: true, this will throw an undefined access error rather than a clear test failure.

🛡️ Proposed defensive assertion
       expect(result.success).toBe(true);
+      expect(result.generated.length).toBeGreaterThan(0);
       const instruction = result.generated[0];
packages/cli/src/commands/primer.ts (1)

103-117: Remove duplicate projectPath parameter.

projectPath is passed both as the first positional argument to generatePrimer() and again inside the options object at line 110. This is redundant and could cause confusion if the two values ever diverge.

♻️ Proposed fix
       const result = generatePrimer(projectPath, {
-        projectPath,
         agents,
         allAgents: this.allAgents,
         outputDir: this.output ? resolve(this.output) : undefined,

Comment thread packages/core/src/primer/analyzer.ts
Comment thread packages/core/src/primer/generator.ts
Comment thread README.md
- Fix OS-agnostic path handling in analyzer using path.relative() and path.sep
- Prevent output collisions when multiple agents produce same filename
- Add defensive check in test before accessing generated[0]
- Remove duplicate projectPath parameter in CLI primer command
- Use PackageManager enum instead of z.string() for type safety
- Detect monorepos before src-based layout to prevent misclassification
- Document --output and --json flags in README examples

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Devin Review found 1 new potential issue.

View issue and 6 additional flags in Devin Review.

Open in Devin Review

Comment thread packages/core/src/primer/analyzer.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/core/src/primer/analyzer.ts`:
- Around line 234-240: The language detection block in Analyzer (method using
this.hasFile and pushing to languages) always sets source to 'pyproject.toml'
even when the match came from 'requirements.txt' or 'setup.py'; update the logic
in the analyzer.ts routine that builds the languages array (where hasFile is
called) to determine the actual matched filename and set source to that filename
(e.g., 'pyproject.toml', 'requirements.txt', or 'setup.py') instead of
hardcoding 'pyproject.toml' so the pushed object accurately reflects which file
triggered the Python detection.

In `@packages/core/src/primer/generator.ts`:
- Around line 174-181: getDefaultTemplate currently hardcodes format:
'markdown', which can produce files in the wrong format for agents whose
configurations in AGENT_CONFIG specify other formats (e.g., gemini-cli -> json,
cursor -> mdc); update getDefaultTemplate (in
packages/core/src/primer/generator.ts) to derive the default format from the
agent's entry in AGENT_CONFIG (use AgentType to look up
AGENT_CONFIG[agent].format or a sensible fallback like 'markdown') so the
returned AgentInstructionTemplate uses the agent-specific format rather than
always 'markdown'.
🧹 Nitpick comments (4)
packages/core/src/primer/generator.ts (1)

15-48: Consider deriving ALL_AGENTS from AGENT_CONFIG for consistency.

The ALL_AGENTS array is hardcoded separately from AGENT_CONFIG. If an agent is added to AGENT_CONFIG but not here (or vice versa), they'll diverge silently.

♻️ Suggested refactor to derive from AGENT_CONFIG
-const ALL_AGENTS: AgentType[] = [
-  'claude-code',
-  'cursor',
-  // ... all 32 agents
-];
+const ALL_AGENTS: AgentType[] = Object.keys(AGENT_CONFIG) as AgentType[];
packages/core/src/primer/analyzer.ts (3)

177-205: Regex-based TOML parsing may be fragile for complex files.

The regex patterns for pyproject.toml and Cargo.toml work for simple cases but could miss values with inline comments, multiline strings, or complex quoting. Consider this a known limitation.

For more robust parsing in the future, consider using a TOML parser library like @iarna/toml or smol-toml. However, the current approach is acceptable for typical project files.


406-418: Questionable heuristic: path aliases implying camelCase.

Setting namingStyle: 'camelCase' based on the presence of @-prefixed path aliases seems unrelated. Path aliases don't indicate naming conventions.

Consider removing this heuristic or replacing it with actual naming pattern detection from source files if needed in the future.


581-596: Unclear directory count estimation logic.

The division by 3 at line 594 (Math.floor(directories / 3)) is unexplained. The directories variable counts files with path separators, not actual unique directories. This metric may be confusing.

Consider either documenting this heuristic or computing actual unique directory count:

 private estimateCodebaseSize(): PrimerAnalysis['codebaseSize'] {
   let files = 0;
-  let directories = 0;
+  const directories = new Set<string>();

   for (const file of this.files) {
-    if (file.includes(sep)) {
-      directories++;
-    }
+    const dir = file.split(sep).slice(0, -1).join(sep);
+    if (dir) directories.add(dir);
     files++;
   }

   return {
     files,
-    directories: Math.floor(directories / 3),
+    directories: directories.size,
   };
 }

Comment thread packages/core/src/primer/analyzer.ts
Comment on lines +174 to +181
private getDefaultTemplate(agent: AgentType, config: AgentDirectoryConfig): AgentInstructionTemplate {
return {
agent,
filename: config.configFile,
format: 'markdown',
sectionOrder: ['overview', 'stack', 'commands', 'conventions', 'structure', 'guidelines'],
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Default template format may mismatch agent's expected format.

getDefaultTemplate hardcodes format: 'markdown', but AGENT_CONFIG specifies different formats for various agents (e.g., gemini-cli uses json, cursor uses mdc). This could generate incorrectly formatted files for agents without explicit templates.

🛠️ Suggested fix to use agent's configured format
 private getDefaultTemplate(agent: AgentType, config: AgentDirectoryConfig): AgentInstructionTemplate {
+  const formatMap: Record<AgentDirectoryConfig['configFormat'], AgentInstructionTemplate['format']> = {
+    'xml': 'markdown',
+    'markdown': 'markdown',
+    'mdc': 'mdc',
+    'json': 'json',
+    'markdown-table': 'markdown',
+  };
   return {
     agent,
     filename: config.configFile,
-    format: 'markdown',
+    format: formatMap[config.configFormat] || 'markdown',
     sectionOrder: ['overview', 'stack', 'commands', 'conventions', 'structure', 'guidelines'],
   };
 }
🤖 Prompt for AI Agents
In `@packages/core/src/primer/generator.ts` around lines 174 - 181,
getDefaultTemplate currently hardcodes format: 'markdown', which can produce
files in the wrong format for agents whose configurations in AGENT_CONFIG
specify other formats (e.g., gemini-cli -> json, cursor -> mdc); update
getDefaultTemplate (in packages/core/src/primer/generator.ts) to derive the
default format from the agent's entry in AGENT_CONFIG (use AgentType to look up
AGENT_CONFIG[agent].format or a sensible fallback like 'markdown') so the
returned AgentInstructionTemplate uses the agent-specific format rather than
always 'markdown'.

- Fix Python detection to use correct source file (pyproject.toml, requirements.txt, or setup.py)
- Escape regex special characters in glob pattern matching (e.g., *.module.css)
- Derive ALL_AGENTS from AGENT_CONFIG to avoid divergence
- Map agent config format to template format based on file extension

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/core/src/primer/generator.ts`:
- Around line 161-188: generateContent currently hardcodes Markdown; update it
to respect template.format by passing the format into the section generation
flow and selecting format-specific renderers instead of always producing
Markdown. Concretely, change generateContent to read template.format (e.g.,
'md', 'mdc', 'json', 'xml'), pass that format into generateSection (and in turn
into generateOverviewSection, generateCapabilitiesSection, etc.), or dispatch to
format-specific helper functions that emit header/footer/customInstructions in
the correct syntax; ensure generateSection signature and all section generators
are updated to accept the format and produce the appropriate output so agents
(like the cursor agent targeting .mdc) get the correct format.

Comment thread packages/core/src/primer/generator.ts
Refactored generateContent to properly respect the format field
instead of always producing Markdown output.

- Added FormatRenderer interface with format-specific implementations
- Created renderers for markdown, mdc, json, xml formats
- JSON format generates structured data via generateJsonContent()
- MDC format includes YAML frontmatter via wrap() method
- XML format properly escapes content with escapeXml()
- Updated all section generators to accept and use the renderer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant