mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-06 09:53:07 +00:00
- Changed model identifier from `claude-opus-4-5-20251101` to `claude-opus-4-6` across various files, including documentation and code references. - Updated the SDK to support adaptive thinking for Opus 4.6, allowing the model to determine its own reasoning depth. - Enhanced the thinking level options to include 'adaptive' and adjusted related components to reflect this change. - Updated tests to ensure compatibility with the new model and its features. These changes improve the model's capabilities and user experience by leveraging adaptive reasoning.
451 lines
13 KiB
Markdown
451 lines
13 KiB
Markdown
# 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
|
|
├── prompts/ # AI prompt templates
|
|
├── 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/prompts
|
|
|
|
**Use when:** You need AI prompt templates for text enhancement or other AI-powered features.
|
|
|
|
**Import for:**
|
|
|
|
- `getEnhancementPrompt(mode)` - Get complete prompt for enhancement mode
|
|
- `getSystemPrompt(mode)` - Get system prompt for specific mode
|
|
- `getExamples(mode)` - Get few-shot examples for a mode
|
|
- `buildUserPrompt(description, mode)` - Build user prompt with examples
|
|
- `isValidEnhancementMode(mode)` - Check if mode is valid
|
|
- `IMPROVE_SYSTEM_PROMPT` - System prompt for improving vague descriptions
|
|
- `TECHNICAL_SYSTEM_PROMPT` - System prompt for adding technical details
|
|
- `SIMPLIFY_SYSTEM_PROMPT` - System prompt for simplifying verbose text
|
|
- `ACCEPTANCE_SYSTEM_PROMPT` - System prompt for adding acceptance criteria
|
|
|
|
**Example:**
|
|
|
|
```typescript
|
|
import { getEnhancementPrompt, isValidEnhancementMode } from '@automaker/prompts';
|
|
|
|
if (isValidEnhancementMode('improve')) {
|
|
const { systemPrompt, userPrompt } = getEnhancementPrompt('improve', description);
|
|
const result = await callClaude(systemPrompt, userPrompt);
|
|
}
|
|
```
|
|
|
|
**Never import from:** `lib/enhancement-prompts`
|
|
|
|
**Enhancement modes:**
|
|
|
|
- `improve` - Transform vague requests into clear, actionable tasks
|
|
- `technical` - Add implementation details and technical specifications
|
|
- `simplify` - Make verbose descriptions concise and focused
|
|
- `acceptance` - Add testable acceptance criteria
|
|
|
|
### @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-6` (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 prompts from @automaker/prompts
|
|
import { getEnhancementPrompt, isValidEnhancementMode } from '@automaker/prompts';
|
|
|
|
// 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'; // ❌
|
|
import { getEnhancementPrompt } from '../lib/enhancement-prompts'; // ❌
|
|
|
|
// 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 prompt templates use `@automaker/prompts`
|
|
- [ ] 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/prompts
|
|
@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 from workspace
|
|
npm run build:packages
|
|
|
|
# Or from root
|
|
npm install # Installs and links workspace packages
|
|
```
|
|
|
|
## Module Format
|
|
|
|
All packages use ES modules (`type: "module"`) with NodeNext module resolution:
|
|
|
|
- Requires explicit `.js` extensions in import statements
|
|
- Compatible with both Node.js (server) and Vite (UI)
|
|
- Centralized ESM configuration in `libs/tsconfig.base.json`
|
|
|
|
## 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/Utils → `@automaker/utils`
|
|
- AI Prompts → `@automaker/prompts`
|
|
- 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.
|