Skip to content

Commit d1b60ac

Browse files
committed
feat: initial opencode-cli with discovery, linker, and schema
- bin/opencode-link.js: CLI entry point for plugin linking - lib/discovery.js: Plugin discovery from global and local node_modules - lib/linker.js: Symlink creation with 'last wins' strategy - lib/schema.js: JSON schema generation for opencode-project.json - lib/index.js: Re-exports all modules Copied from opencode-plugins repository to enable: - Global installation: npm install -g github:techdivision/opencode-cli - Use from anywhere: npx opencode-link
0 parents  commit d1b60ac

9 files changed

Lines changed: 1871 additions & 0 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules/
2+
.DS_Store
3+
*.log
4+
.env

AGENTS.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# AGENTS.md - OpenCode CLI
2+
3+
This file provides guidance for AI coding agents working in this repository.
4+
5+
## Repository Overview
6+
7+
This repository contains the CLI tools for OpenCode plugin management.
8+
9+
- **Type**: CLI tool (ES Module, Node.js)
10+
- **Entry Point**: `bin/opencode-link.js`
11+
- **No external dependencies** - uses Node.js built-ins only
12+
13+
## Project Structure
14+
15+
```
16+
opencode-cli/
17+
├── package.json # NPM package configuration
18+
├── README.md # Documentation
19+
├── AGENTS.md # This file
20+
├── .gitignore
21+
├── bin/
22+
│ └── opencode-link.js # CLI entry point
23+
└── lib/
24+
├── index.js # Re-exports all modules
25+
├── discovery.js # Plugin discovery (global + local)
26+
├── linker.js # Symlink creation utilities
27+
└── schema.js # JSON schema generation
28+
```
29+
30+
## Files
31+
32+
| File | Purpose |
33+
|------|---------|
34+
| `bin/opencode-link.js` | CLI entry point, argument parsing, command dispatch |
35+
| `lib/discovery.js` | Discovers plugins from global npm prefix and local node_modules |
36+
| `lib/linker.js` | Creates symlinks with "last wins" strategy |
37+
| `lib/schema.js` | Generates combined JSON schema from plugin schemas |
38+
| `lib/index.js` | Re-exports all modules for convenience |
39+
40+
## Code Style
41+
42+
- **Module System**: ES Modules (`"type": "module"` in package.json)
43+
- **Node.js APIs**: Use `fs`, `path`, `os`, `child_process` from Node.js built-ins
44+
- **No Dependencies**: Zero external dependencies
45+
- **Formatting**: 2-space indentation, single quotes, semicolons
46+
- **Functions**: Use JSDoc comments for public functions
47+
48+
```javascript
49+
// Good - ES Module imports
50+
import fs from 'fs';
51+
import path from 'path';
52+
import { fileURLToPath } from 'url';
53+
54+
// Good - __dirname equivalent for ES Modules
55+
const __filename = fileURLToPath(import.meta.url);
56+
const __dirname = path.dirname(__filename);
57+
58+
// Good - JSDoc for functions
59+
/**
60+
* Discovers all available plugins from all locations.
61+
* @param {string} targetDir - The .opencode directory
62+
* @returns {Map<string, PluginDescriptor>} Map of plugin name to descriptor
63+
*/
64+
export function discoverPlugins(targetDir) { ... }
65+
```
66+
67+
## Key Concepts
68+
69+
### Plugin Discovery (lib/discovery.js)
70+
71+
Plugins are discovered from two locations:
72+
1. **Global**: `npm config get prefix`/lib/node_modules/
73+
2. **Local**: `{targetDir}/node_modules/`
74+
75+
Priority: **last wins** (local overrides global)
76+
77+
### Plugin Types
78+
79+
- **Monorepo**: Package with subdirectories containing `.opencode/`
80+
- **Singlerepo**: Package with `plugin.json` + content directories in root
81+
82+
### Symlink Strategy (lib/linker.js)
83+
84+
- **LAST WINS**: Existing symlinks are overwritten
85+
- **Real files preserved**: Real files/directories are NOT overwritten
86+
- **Same-source skipped**: Symlinks pointing to same source are skipped
87+
88+
## Testing
89+
90+
```bash
91+
# Link globally for testing
92+
npm link
93+
94+
# Test in a new project
95+
mkdir -p /tmp/test-cli && cd /tmp/test-cli
96+
npx opencode-link list
97+
98+
# Test with opencode-plugins
99+
mkdir -p /tmp/test-cli/.opencode && cd /tmp/test-cli/.opencode
100+
npm install github:techdivision/opencode-plugins
101+
npx opencode-link list
102+
```
103+
104+
## Git Workflow
105+
106+
This repository follows a simple workflow:
107+
108+
1. Work on `main` branch for now (small repo)
109+
2. Use conventional commits: `feat:`, `fix:`, `docs:`, `refactor:`
110+
3. Tag releases: `v0.1.0`, `v0.2.0`, etc.
111+
112+
## Related Repositories
113+
114+
- **opencode-plugins**: Main plugin repository (depends on this CLI)
115+
- **opencode-plugin-time-tracking**: Example singlerepo plugin
116+
- **opencode-plugin-shell-env**: Example singlerepo plugin

README.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# @techdivision/opencode-cli
2+
3+
CLI tools for OpenCode plugin management.
4+
5+
## Prerequisites
6+
7+
- **Node.js** >= 18
8+
- **npm** >= 9
9+
10+
## Installation
11+
12+
### Global (Recommended)
13+
14+
Install once, use everywhere:
15+
16+
```bash
17+
npm install -g github:techdivision/opencode-cli
18+
```
19+
20+
Then use from any project:
21+
22+
```bash
23+
cd /path/to/my-project
24+
npx opencode-link # Link standard plugins
25+
npx opencode-link list # List available plugins
26+
npx opencode-link status # Show current links
27+
```
28+
29+
### As Dependency
30+
31+
Used automatically when you install `@techdivision/opencode-plugins`:
32+
33+
```bash
34+
cd /path/to/my-project/.opencode
35+
npm install github:techdivision/opencode-plugins
36+
npx opencode-link
37+
```
38+
39+
## Commands
40+
41+
| Command | Description |
42+
|---------|-------------|
43+
| `opencode-link` | Link all standard plugins |
44+
| `opencode-link all` | Link ALL plugins (standard + optional) |
45+
| `opencode-link <plugin>` | Link a specific plugin |
46+
| `opencode-link list` | List available plugins |
47+
| `opencode-link status` | Show current links |
48+
| `opencode-link clean` | Remove all symlinks |
49+
| `opencode-link schema` | Regenerate schema |
50+
51+
## Options
52+
53+
| Flag | Description |
54+
|------|-------------|
55+
| `--target-dir=<path>` | Override target directory |
56+
| `--singular` | Use singular directory names (agent/ instead of agents/) |
57+
58+
## Plugin Discovery
59+
60+
Plugins are discovered from two locations (priority: last wins):
61+
62+
1. **Global**: `npm config get prefix`/lib/node_modules/
63+
2. **Local**: `{project}/.opencode/node_modules/`
64+
65+
Each location can contain:
66+
- **Monorepo**: Package with subdirectories containing `.opencode/` (e.g., opencode-plugins)
67+
- **Singlerepo**: Package with `plugin.json` + content dirs in root (e.g., opencode-plugin-time-tracking)
68+
69+
## Programmatic Usage
70+
71+
You can also use the CLI modules programmatically:
72+
73+
```javascript
74+
import { discoverPlugins, getContentTypes } from '@techdivision/opencode-cli/discovery';
75+
import { createSymlink, getItemsToLink } from '@techdivision/opencode-cli/linker';
76+
import { generateCombinedSchema } from '@techdivision/opencode-cli/schema';
77+
78+
// Discover plugins
79+
const plugins = discoverPlugins('/path/to/.opencode');
80+
console.log(`Found ${plugins.size} plugins`);
81+
82+
// Get all content types
83+
const types = getContentTypes(plugins);
84+
console.log(`Content types: ${types.join(', ')}`);
85+
```
86+
87+
## License
88+
89+
MIT

0 commit comments

Comments
 (0)