docs: add comprehensive documentation for shared packages

- Added README.md for all 6 shared packages:
  - @automaker/types: Type definitions and interfaces
  - @automaker/utils: Utility functions (logger, error handling, images)
  - @automaker/platform: Platform utilities (paths, subprocess, security)
  - @automaker/model-resolver: Claude model resolution
  - @automaker/dependency-resolver: Feature dependency ordering
  - @automaker/git-utils: Git operations and diff generation

- Removed MIT license from all package.json files (using custom dual license)

- Created comprehensive LLM guide (docs/llm-shared-packages.md):
  - When to use each package
  - Import patterns and examples
  - Common usage patterns
  - Migration checklist
  - Do's and don'ts for LLMs

Documentation helps developers and AI assistants understand package purpose,
usage, and best practices.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Kacper
2025-12-19 23:52:42 +01:00
parent 060a789b45
commit 7ad7b63da2
13 changed files with 1351 additions and 6 deletions

388
docs/llm-shared-packages.md Normal file
View File

@@ -0,0 +1,388 @@
# AutoMaker Shared Packages - LLM Guide
This guide helps AI assistants understand how to use AutoMaker's shared packages effectively.
## Package Overview
AutoMaker uses a monorepo structure with shared packages in `libs/`:
```
libs/
├── types/ # Type definitions (no dependencies)
├── utils/ # Utility functions
├── platform/ # Platform utilities
├── model-resolver/ # Claude model resolution
├── dependency-resolver/# Feature dependency resolution
└── git-utils/ # Git operations
```
## When to Use Each Package
### @automaker/types
**Use when:** You need type definitions for any AutoMaker concept.
**Import for:**
- `Feature` - Feature interface with all properties
- `ExecuteOptions` - Claude agent execution options
- `ConversationMessage` - Chat message format
- `ErrorType`, `ErrorInfo` - Error handling types
- `CLAUDE_MODEL_MAP` - Model alias to ID mapping
- `DEFAULT_MODELS` - Default model configurations
**Example:**
```typescript
import type { Feature, ExecuteOptions } from '@automaker/types';
```
**Never import from:** `services/feature-loader`, `providers/types`
### @automaker/utils
**Use when:** You need common utilities like logging, error handling, or image processing.
**Import for:**
- `createLogger(context)` - Structured logging
- `isAbortError(error)` - Error type checking
- `classifyError(error)` - Error classification
- `buildPromptWithImages()` - Prompt building with images
- `readImageAsBase64()` - Image handling
- `extractTextFromContent()` - Message parsing
**Example:**
```typescript
import { createLogger, classifyError } from '@automaker/utils';
```
**Never import from:** `lib/logger`, `lib/error-handler`, `lib/prompt-builder`, `lib/image-handler`
### @automaker/platform
**Use when:** You need to work with AutoMaker's directory structure or spawn processes.
**Import for:**
- `getAutomakerDir(projectPath)` - Get .automaker directory
- `getFeaturesDir(projectPath)` - Get features directory
- `getFeatureDir(projectPath, featureId)` - Get specific feature directory
- `ensureAutomakerDir(projectPath)` - Create .automaker if needed
- `spawnJSONLProcess()` - Spawn process with JSONL output
- `initAllowedPaths()` - Security path validation
**Example:**
```typescript
import { getFeatureDir, ensureAutomakerDir } from '@automaker/platform';
```
**Never import from:** `lib/automaker-paths`, `lib/subprocess-manager`, `lib/security`
### @automaker/model-resolver
**Use when:** You need to convert model aliases to full model IDs.
**Import for:**
- `resolveModelString(modelOrAlias)` - Convert alias to full ID
- `DEFAULT_MODELS` - Access default models
**Example:**
```typescript
import { resolveModelString, DEFAULT_MODELS } from '@automaker/model-resolver';
// Convert user input to model ID
const modelId = resolveModelString('sonnet'); // → 'claude-sonnet-4-20250514'
```
**Never import from:** `lib/model-resolver`
**Model aliases:**
- `haiku``claude-haiku-4-5` (fast, simple tasks)
- `sonnet``claude-sonnet-4-20250514` (balanced, recommended)
- `opus``claude-opus-4-5-20251101` (maximum capability)
### @automaker/dependency-resolver
**Use when:** You need to order features by dependencies or check if dependencies are satisfied.
**Import for:**
- `resolveDependencies(features)` - Topological sort with priority
- `areDependenciesSatisfied(feature, allFeatures)` - Check if ready to execute
- `getBlockingDependencies(feature, allFeatures)` - Get incomplete dependencies
**Example:**
```typescript
import { resolveDependencies, areDependenciesSatisfied } from '@automaker/dependency-resolver';
const { orderedFeatures, hasCycle } = resolveDependencies(features);
if (!hasCycle) {
for (const feature of orderedFeatures) {
if (areDependenciesSatisfied(feature, features)) {
await execute(feature);
}
}
}
```
**Never import from:** `lib/dependency-resolver`
**Used in:**
- Auto-mode feature execution (server)
- Board view feature ordering (UI)
### @automaker/git-utils
**Use when:** You need git operations, status parsing, or diff generation.
**Import for:**
- `isGitRepo(path)` - Check if path is a git repository
- `parseGitStatus(output)` - Parse `git status --porcelain` output
- `getGitRepositoryDiffs(path)` - Get complete diffs (tracked + untracked)
- `generateSyntheticDiffForNewFile()` - Create diff for untracked file
- `listAllFilesInDirectory()` - List files excluding build artifacts
**Example:**
```typescript
import { isGitRepo, getGitRepositoryDiffs } from '@automaker/git-utils';
if (await isGitRepo(projectPath)) {
const { diff, files, hasChanges } = await getGitRepositoryDiffs(projectPath);
console.log(`Found ${files.length} changed files`);
}
```
**Never import from:** `routes/common`
**Handles:**
- Binary file detection
- Large file handling (>1MB)
- Untracked file diffs
- Non-git directory support
## Common Patterns
### Creating a Feature Executor
```typescript
import type { Feature, ExecuteOptions } from '@automaker/types';
import { createLogger, classifyError } from '@automaker/utils';
import { resolveModelString, DEFAULT_MODELS } from '@automaker/model-resolver';
import { areDependenciesSatisfied } from '@automaker/dependency-resolver';
import { getFeatureDir } from '@automaker/platform';
const logger = createLogger('FeatureExecutor');
async function executeFeature(
feature: Feature,
allFeatures: Feature[],
projectPath: string
) {
// Check dependencies
if (!areDependenciesSatisfied(feature, allFeatures)) {
logger.warn(`Dependencies not satisfied for ${feature.id}`);
return;
}
// Resolve model
const model = resolveModelString(feature.model, DEFAULT_MODELS.autoMode);
// Get feature directory
const featureDir = getFeatureDir(projectPath, feature.id);
try {
// Execute with Claude
const options: ExecuteOptions = {
model,
temperature: 0.7
};
await runAgent(featureDir, options);
logger.info(`Feature ${feature.id} completed`);
} catch (error) {
const errorInfo = classifyError(error);
logger.error(`Feature ${feature.id} failed:`, errorInfo.message);
}
}
```
### Analyzing Git Changes
```typescript
import { getGitRepositoryDiffs, parseGitStatus } from '@automaker/git-utils';
import { createLogger } from '@automaker/utils';
const logger = createLogger('GitAnalyzer');
async function analyzeChanges(projectPath: string) {
const { diff, files, hasChanges } = await getGitRepositoryDiffs(projectPath);
if (!hasChanges) {
logger.info('No changes detected');
return;
}
// Group by status
const modified = files.filter(f => f.status === 'M');
const added = files.filter(f => f.status === 'A');
const deleted = files.filter(f => f.status === 'D');
const untracked = files.filter(f => f.status === '?');
logger.info(`Changes: ${modified.length}M ${added.length}A ${deleted.length}D ${untracked.length}U`);
return diff;
}
```
### Ordering Features for Execution
```typescript
import type { Feature } from '@automaker/types';
import { resolveDependencies, getBlockingDependencies } from '@automaker/dependency-resolver';
import { createLogger } from '@automaker/utils';
const logger = createLogger('FeatureOrdering');
function orderAndFilterFeatures(features: Feature[]): Feature[] {
const { orderedFeatures, hasCycle, cyclicFeatures } = resolveDependencies(features);
if (hasCycle) {
logger.error(`Circular dependency detected: ${cyclicFeatures.join(' → ')}`);
throw new Error('Cannot execute features with circular dependencies');
}
// Filter to only ready features
const readyFeatures = orderedFeatures.filter(feature => {
const blocking = getBlockingDependencies(feature, features);
if (blocking.length > 0) {
logger.debug(`${feature.id} blocked by: ${blocking.join(', ')}`);
return false;
}
return true;
});
logger.info(`${readyFeatures.length} of ${features.length} features ready`);
return readyFeatures;
}
```
## Import Rules for LLMs
### ✅ DO
```typescript
// Import types from @automaker/types
import type { Feature, ExecuteOptions } from '@automaker/types';
// Import constants from @automaker/types
import { CLAUDE_MODEL_MAP, DEFAULT_MODELS } from '@automaker/types';
// Import utilities from @automaker/utils
import { createLogger, classifyError } from '@automaker/utils';
// Import platform utils from @automaker/platform
import { getFeatureDir, ensureAutomakerDir } from '@automaker/platform';
// Import model resolution from @automaker/model-resolver
import { resolveModelString } from '@automaker/model-resolver';
// Import dependency resolution from @automaker/dependency-resolver
import { resolveDependencies } from '@automaker/dependency-resolver';
// Import git utils from @automaker/git-utils
import { getGitRepositoryDiffs } from '@automaker/git-utils';
```
### ❌ DON'T
```typescript
// DON'T import from old paths
import { Feature } from '../services/feature-loader'; // ❌
import { ExecuteOptions } from '../providers/types'; // ❌
import { createLogger } from '../lib/logger'; // ❌
import { resolveModelString } from '../lib/model-resolver'; // ❌
import { isGitRepo } from '../routes/common'; // ❌
import { resolveDependencies } from '../lib/dependency-resolver'; // ❌
// DON'T import from old lib/ paths
import { getFeatureDir } from '../lib/automaker-paths'; // ❌
import { classifyError } from '../lib/error-handler'; // ❌
// DON'T define types that exist in @automaker/types
interface Feature { ... } // ❌ Use: import type { Feature } from '@automaker/types';
```
## Migration Checklist
When refactoring server code, check:
- [ ] All `Feature` imports use `@automaker/types`
- [ ] All `ExecuteOptions` imports use `@automaker/types`
- [ ] All logger usage uses `@automaker/utils`
- [ ] All path operations use `@automaker/platform`
- [ ] All model resolution uses `@automaker/model-resolver`
- [ ] All dependency checks use `@automaker/dependency-resolver`
- [ ] All git operations use `@automaker/git-utils`
- [ ] No imports from old `lib/` paths
- [ ] No imports from `services/feature-loader` for types
- [ ] No imports from `providers/types`
## Package Dependencies
Understanding the dependency chain helps prevent circular dependencies:
```
@automaker/types (no dependencies)
@automaker/utils
@automaker/platform
@automaker/model-resolver
@automaker/dependency-resolver
@automaker/git-utils
@automaker/server
@automaker/ui
```
**Rule:** Packages can only depend on packages above them in the chain.
## Building Packages
All packages must be built before use:
```bash
# Build all packages
cd libs/types && npm run build
cd libs/utils && npm run build
cd libs/platform && npm run build
cd libs/model-resolver && npm run build
cd libs/dependency-resolver && npm run build
cd libs/git-utils && npm run build
# Or from root
npm install # Installs and links workspace packages
```
## Module Format
- **dependency-resolver**: ES modules (`type: "module"`) for Vite compatibility
- **All others**: CommonJS for Node.js compatibility
## Testing
When writing tests:
```typescript
// ✅ Import from packages
import type { Feature } from '@automaker/types';
import { createLogger } from '@automaker/utils';
// ❌ Don't import from src
import { Feature } from '../../../src/services/feature-loader';
```
## Summary for LLMs
**Quick reference:**
- Types → `@automaker/types`
- Logging/Errors → `@automaker/utils`
- Paths/Security → `@automaker/platform`
- Model Resolution → `@automaker/model-resolver`
- Dependency Ordering → `@automaker/dependency-resolver`
- Git Operations → `@automaker/git-utils`
**Never import from:** `lib/*`, `services/feature-loader` (for types), `providers/types`, `routes/common`
**Always:** Use the shared packages instead of local implementations.