Skip to content

Commit 3cba4e2

Browse files
committed
feat: Added CLAUDE.md and README.md
1 parent 3987079 commit 3cba4e2

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

CLAUDE.md

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Overview
6+
7+
`@codifycli/plugin-core` is a TypeScript library for building Codify plugins. Codify is an infrastructure-as-code tool
8+
that manages system resources (applications, CLI tools, settings) through a declarative JSON configuration. This library
9+
provides the core abstractions and runtime for implementing plugins that can create, modify, and destroy system
10+
resources.
11+
12+
## Development Commands
13+
14+
### Testing
15+
16+
```bash
17+
# Run all tests with Vitest
18+
npm test
19+
20+
# Note: `npm test` also runs TypeScript compilation as a posttest step
21+
```
22+
23+
### Building
24+
25+
```bash
26+
# Compile TypeScript to dist/
27+
npm run prepublishOnly
28+
29+
# Or just compile directly
30+
npx tsc
31+
```
32+
33+
### Linting
34+
35+
```bash
36+
# Lint with ESLint (oclif + oclif-typescript + prettier configs)
37+
npx eslint src/
38+
```
39+
40+
### CLI Tool
41+
42+
The package includes a `codify-build` CLI tool (in `bin/build.js`) used by plugin implementations to generate
43+
documentation and validate schemas.
44+
45+
## Architecture
46+
47+
### Core Concepts
48+
49+
**Plugin System Architecture:**
50+
51+
- **Plugin** (`src/plugin/plugin.ts`): Top-level container that manages multiple resource types and handles IPC
52+
communication with the Codify CLI via the MessageHandler
53+
- **Resource** (`src/resource/resource.ts`): Abstract base class representing a manageable system resource (e.g.,
54+
homebrew, git config, applications). Each resource must implement:
55+
- `refresh()`: Query current system state
56+
- `create()`: Install/create the resource
57+
- `destroy()`: Uninstall/remove the resource
58+
- `modify()`: Update individual parameters (optional)
59+
- **Plan** (`src/plan/plan.ts`): Represents a set of changes to transform current state into desired state, similar to
60+
Terraform plans. Contains a ChangeSet with parameter-level operations (ADD/REMOVE/MODIFY/NO-OP) and resource-level
61+
operation (CREATE/DESTROY/MODIFY/RECREATE/NO-OP)
62+
- **ResourceController** (`src/resource/resource-controller.ts`): Orchestrates the full lifecycle: validation →
63+
planning → application. Handles both stateful mode (tracks state between runs) and stateless mode (declarative only)
64+
65+
**Stateful vs Stateless Modes:**
66+
67+
- **Stateless**: Plans computed by comparing desired config against current system state. Only manages parameters
68+
explicitly declared in config.
69+
- **Stateful**: Tracks previous state. Enables destroy operations and more granular change detection. Plans compare
70+
desired vs state, then match state to current system state.
71+
72+
**Stateful Parameters** (`src/stateful-parameter/stateful-parameter.ts`):
73+
74+
- Parameters that have their own lifecycle tied to the parent resource (e.g., homebrew formulas, nvm node versions)
75+
- Implement their own `refresh()`, `add()`, `modify()`, `remove()` methods
76+
- Can be array-based (`ArrayStatefulParameter`) for managing collections
77+
78+
**PTY Abstraction** (`src/pty/`):
79+
80+
- `BackgroundPty`: Executes commands asynchronously during refresh/plan operations. Multiple commands can run in
81+
parallel. Killed after planning completes.
82+
- `SequentialPty`: Executes commands synchronously during apply operations to ensure ordered execution and proper error
83+
handling
84+
- `getPty()`: Access current PTY from async local storage context
85+
- All shell execution goes through this abstraction for consistent output handling and root privilege escalation
86+
87+
**IPC Communication** (`src/messages/`):
88+
89+
- `MessageHandler`: Processes messages from Codify CLI (initialize, plan, apply, validate, import, match)
90+
- `MessageSender`: Sends responses and requests (e.g., sudo password prompts) back to CLI
91+
- Messages validated against schemas from `@codifycli/schemas`
92+
93+
### Directory Structure
94+
95+
```
96+
src/
97+
├── plugin/ - Plugin class and main entry point
98+
├── resource/ - Resource base class, settings, controller
99+
├── plan/ - Plan calculation and change set logic
100+
├── stateful-parameter/ - Stateful parameter abstractions
101+
├── pty/ - Pseudo-terminal abstraction for shell commands
102+
├── messages/ - IPC message handlers and senders
103+
├── utils/ - File utilities, path resolution, debug logging
104+
└── common/ - Shared errors and types
105+
```
106+
107+
### Key Files
108+
109+
- `src/index.ts`: Main entry point with `runPlugin()` function
110+
- `src/plugin/plugin.ts`: Core plugin implementation (~290 lines)
111+
- `src/resource/resource.ts`: Abstract Resource class
112+
- `src/resource/resource-controller.ts`: Resource lifecycle orchestration
113+
- `src/resource/resource-settings.ts`: Configuration schema for resources (parameter settings, OS support, allow
114+
multiple, etc.)
115+
- `src/plan/plan.ts`: Plan calculation logic (~500 lines)
116+
- `src/plan/change-set.ts`: Parameter-level diff algorithm
117+
- `bin/build.js`: Documentation/schema builder for plugin implementations
118+
119+
### Resource Settings
120+
121+
Resources are configured via `ResourceSettings<T>` returned by `getSettings()`:
122+
123+
- `id`: Unique type identifier
124+
- `schema`: JSON Schema or Zod schema for validation
125+
- `operatingSystems`: Supported OS platforms (darwin/linux/win32)
126+
- `linuxDistros`: Supported Linux distributions (optional)
127+
- `allowMultiple`: Whether multiple instances can coexist (requires `matcher` function)
128+
- `parameterSettings`: Per-parameter configuration (equals functions, transformations, stateful types, sensitivity)
129+
- `isSensitive`: Marks resource as sensitive (prevents auto-import, hides values)
130+
- `dependencies`: Resource IDs this resource depends on
131+
- `canDestroy`: Whether resource can be destroyed (default: true)
132+
133+
## Implementation Notes
134+
135+
### Testing
136+
137+
- Uses Vitest with `pool: 'forks'` configuration for isolated test execution
138+
- Test files use `.test.ts` suffix and are excluded from compilation
139+
- TypeScript compilation runs as a posttest step to catch type errors
140+
141+
### Module System
142+
143+
- Uses ES modules (`"type": "module"` in package.json)
144+
- Module resolution: `Node16` with `.js` extensions in imports (even for `.ts` files)
145+
- Target: ES2022
146+
- Requires Node.js >=22.0.0
147+
148+
### Parameter Matching and Filtering
149+
150+
Array parameters support custom matching logic:
151+
152+
- `isElementEqual`: Function to compare array elements
153+
- `filterInStatelessMode`: Controls how current state is filtered against desired state in stateless mode
154+
- Default behavior: filters current arrays to only include elements matching desired config (prevents spurious deletes)
155+
156+
### Path Handling
157+
158+
Utility functions in `src/utils/functions.ts`:
159+
160+
- `tildify()`: Convert absolute paths to use `~`
161+
- `untildify()`: Expand `~` to home directory
162+
- `resolvePathWithVariables()`: Resolve paths with variables like `$CODIFY_*`
163+
- Path transformations are commonly used in `InputTransformation` for file/directory parameters
164+
165+
### CI/CD
166+
167+
GitHub Actions workflow (`.github/workflows/unit-test-ci.yaml`):
168+
169+
- Runs on push to any branch
170+
- Tests on: `ubuntu-latest`, `macos-latest`
171+
- Node.js version: 22.x
172+
- Commands: `npm ci``npm run test`
173+
174+
### Dependencies
175+
176+
Key dependencies:
177+
178+
- `@codifycli/schemas`: Shared schema definitions and types
179+
- `@homebridge/node-pty-prebuilt-multiarch`: PTY for shell command execution
180+
- `ajv`: JSON Schema validation
181+
- `zod`: Alternative schema validation (v4)
182+
- `clean-deep`: Remove null/undefined from objects
183+
- `lodash.isequal`: Deep equality checks

0 commit comments

Comments
 (0)