|
| 1 | +--- |
| 2 | +phase: design |
| 3 | +title: System Design & Architecture |
| 4 | +description: Define the technical architecture, components, and data models |
| 5 | +feature: global-setup |
| 6 | +--- |
| 7 | + |
| 8 | +# System Design & Architecture - Global Setup Feature |
| 9 | + |
| 10 | +## Architecture Overview |
| 11 | +**What is the high-level system structure?** |
| 12 | + |
| 13 | +```mermaid |
| 14 | +graph TD |
| 15 | + CLI[CLI: ai-devkit setup --global] --> Selector[EnvironmentSelector] |
| 16 | + Selector -->|Filter by globalCommandPath| GlobalEnvs[Global-capable Environments] |
| 17 | + GlobalEnvs --> User[User Selection] |
| 18 | + User --> TM[TemplateManager] |
| 19 | + TM -->|Copy commands| GlobalFolder[~/.gemini/antigravity/global_workflows/ or ~/.codex/prompts/] |
| 20 | +``` |
| 21 | + |
| 22 | +**Key components and their responsibilities:** |
| 23 | +- **CLI (`src/cli.ts`)**: Adds new `setup` command with `--global` flag |
| 24 | +- **EnvironmentSelector (`src/lib/EnvironmentSelector.ts`)**: New method to select only global-capable environments |
| 25 | +- **TemplateManager (`src/lib/TemplateManager.ts`)**: New method to copy commands to global folders |
| 26 | +- **Environment Definitions (`src/util/env.ts`)**: New `globalCommandPath` property to indicate global support |
| 27 | + |
| 28 | +**Technology stack choices:** |
| 29 | +- Use existing `fs-extra` for file operations with `os.homedir()` for home directory resolution |
| 30 | +- Use existing `inquirer` for user prompts |
| 31 | + |
| 32 | +## Data Models |
| 33 | +**What data do we need to manage?** |
| 34 | + |
| 35 | +### EnvironmentDefinition (Updated) |
| 36 | +```typescript |
| 37 | +export interface EnvironmentDefinition { |
| 38 | + code: string; |
| 39 | + name: string; |
| 40 | + contextFileName: string; |
| 41 | + commandPath: string; |
| 42 | + description?: string; |
| 43 | + isCustomCommandPath?: boolean; |
| 44 | + customCommandExtension?: string; |
| 45 | + globalCommandPath?: string; // NEW: Path relative to home dir for global commands |
| 46 | +} |
| 47 | +``` |
| 48 | + |
| 49 | +### Environment Definitions with Global Support |
| 50 | +```typescript |
| 51 | +antigravity: { |
| 52 | + code: 'antigravity', |
| 53 | + name: 'Antigravity', |
| 54 | + contextFileName: 'AGENTS.md', |
| 55 | + commandPath: '.agent/workflows', |
| 56 | + globalCommandPath: '.gemini/antigravity/global_workflows', // NEW |
| 57 | +}, |
| 58 | +codex: { |
| 59 | + code: 'codex', |
| 60 | + name: 'OpenAI Codex', |
| 61 | + contextFileName: 'AGENTS.md', |
| 62 | + commandPath: '.codex/commands', |
| 63 | + globalCommandPath: '.codex/prompts', // NEW |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +## API Design |
| 68 | +**How do components communicate?** |
| 69 | + |
| 70 | +### New CLI Command |
| 71 | +```bash |
| 72 | +ai-devkit setup --global |
| 73 | +``` |
| 74 | + |
| 75 | +### New/Modified Functions |
| 76 | + |
| 77 | +**`src/util/env.ts`:** |
| 78 | +```typescript |
| 79 | +// Get only environments that support global setup |
| 80 | +export function getGlobalCapableEnvironments(): EnvironmentDefinition[]; |
| 81 | + |
| 82 | +// Check if an environment supports global setup |
| 83 | +export function hasGlobalSupport(envCode: EnvironmentCode): boolean; |
| 84 | +``` |
| 85 | + |
| 86 | +**`src/lib/EnvironmentSelector.ts`:** |
| 87 | +```typescript |
| 88 | +// Select from global-capable environments only |
| 89 | +async selectGlobalEnvironments(): Promise<EnvironmentCode[]>; |
| 90 | +``` |
| 91 | + |
| 92 | +**`src/lib/TemplateManager.ts`:** |
| 93 | +```typescript |
| 94 | +// Copy commands to global folder |
| 95 | +async copyCommandsToGlobal(envCode: EnvironmentCode): Promise<string[]>; |
| 96 | + |
| 97 | +// Check if global commands exist |
| 98 | +async checkGlobalCommandsExist(envCode: EnvironmentCode): Promise<boolean>; |
| 99 | +``` |
| 100 | + |
| 101 | +## Component Breakdown |
| 102 | +**What are the major building blocks?** |
| 103 | + |
| 104 | +### 1. Types Update (`src/types.ts`) |
| 105 | +- Add `globalCommandPath?: string` to `EnvironmentDefinition` |
| 106 | + |
| 107 | +### 2. Environment Definitions Update (`src/util/env.ts`) |
| 108 | +- Add `globalCommandPath` to Antigravity and Codex definitions |
| 109 | +- Add `getGlobalCapableEnvironments()` function |
| 110 | +- Add `hasGlobalSupport()` function |
| 111 | + |
| 112 | +### 3. EnvironmentSelector Update (`src/lib/EnvironmentSelector.ts`) |
| 113 | +- Add `selectGlobalEnvironments()` method that filters to global-capable envs |
| 114 | + |
| 115 | +### 4. TemplateManager Update (`src/lib/TemplateManager.ts`) |
| 116 | +- Add `copyCommandsToGlobal()` method |
| 117 | +- Add `checkGlobalCommandsExist()` method |
| 118 | +- Handle home directory resolution with `os.homedir()` |
| 119 | + |
| 120 | +### 5. New Setup Command (`src/commands/setup.ts`) |
| 121 | +- Create new command file for `setup --global` |
| 122 | +- Handle environment selection, overwrite prompts, and file copying |
| 123 | + |
| 124 | +### 6. CLI Update (`src/cli.ts`) |
| 125 | +- Add `setup` command with `--global` flag |
| 126 | + |
| 127 | +## Design Decisions |
| 128 | +**Why did we choose this approach?** |
| 129 | + |
| 130 | +1. **Separate `setup` command vs. extending `init`:** |
| 131 | + - Chosen: New `setup` command with `--global` flag |
| 132 | + - Rationale: Keeps concerns separated; `init` is for project setup, `setup --global` is for global setup |
| 133 | + |
| 134 | +2. **`globalCommandPath` property on EnvironmentDefinition:** |
| 135 | + - Chosen: Optional property that indicates global support |
| 136 | + - Rationale: Extensible - any environment can add global support by defining this property |
| 137 | + - Alternative considered: Separate `GLOBAL_ENVIRONMENTS` constant - less flexible |
| 138 | + |
| 139 | +3. **File extension handling:** |
| 140 | + - Chosen: Use `.md` format for both Antigravity and Codex global commands |
| 141 | + - Rationale: Antigravity global workflows use `.md` format (same as local `.agent/workflows/`), Codex prompts also use `.md` |
| 142 | + - Note: Unlike regular Gemini which uses `.toml`, Antigravity global is different |
| 143 | + |
| 144 | +4. **Overwrite behavior:** |
| 145 | + - Chosen: Check for existing files and prompt user |
| 146 | + - Rationale: Prevents accidental data loss of customized commands |
| 147 | + |
| 148 | +5. **Cross-platform support:** |
| 149 | + - Chosen: Use `os.homedir()` and `path.join()` for path resolution |
| 150 | + - Rationale: Works consistently on macOS, Linux, and Windows |
| 151 | + |
| 152 | +## Non-Functional Requirements |
| 153 | +**How should the system perform?** |
| 154 | + |
| 155 | +**Reliability:** |
| 156 | +- Gracefully handle missing home directory |
| 157 | +- Create global folders if they don't exist |
| 158 | +- Provide clear error messages if file operations fail |
| 159 | + |
| 160 | +**Usability:** |
| 161 | +- Clear prompts for environment selection |
| 162 | +- Informative success/error messages |
| 163 | +- Consistent with existing `init` command UX |
0 commit comments