Purpose: Quick reference for working on the OAC package refactor
Issue: #206
Branch: feature/oac-package-refactor
Context: features/oac-package-refactor.md
✅ Planning Complete
📝 Next: Phase 1 - Core CLI Infrastructure
--yolo): Skip confirmations, auto-resolve, report at endpreferLocal optionoac context resolve, list, validate, override, sync# Switch to feature branch
git checkout feature/oac-package-refactor
# View full context
cat .opencode/context/openagents-repo/features/oac-package-refactor.md
# View GitHub issue
gh issue view 206
# Start Phase 1
# (See Phase 1 section below)
Goal: Set up TypeScript project and configuration system
Set up TypeScript project structure
mkdir -p src/{cli/{commands,config},core/{context,installer,approval},types,utils}
npm install --save-dev typescript @types/node tsx vitest
npx tsc --init
Install CLI dependencies
npm install commander inquirer zod chalk ora boxen
npm install --save-dev @types/inquirer
Create configuration schema (CRITICAL)
src/cli/config/schema.tsconfirmOverwrites, yoloMode, preferLocal, context resolution configCreate configuration manager
src/cli/config/manager.ts~/.config/oac/config.json (global) and .oac/config.json (local)Create approval system (CRITICAL)
src/core/approval/manager.tsCreate context resolver (CRITICAL)
src/core/context/resolver.tspreferLocal configurationImplement basic CLI commands
src/cli/index.ts (Commander setup)src/cli/commands/configure.tssrc/cli/commands/list.tssrc/cli/commands/init.ts--yolo, --dry-run, --local, --globalUpdate bin/oac.js
Write tests
oac configure command worksoac list command worksoac init command works (asks local vs global)oac context resolve command works# Test configuration (global + local)
oac configure show
oac configure set agents.permissions.bash auto
oac configure get agents.permissions.bash
oac configure set preferences.yoloMode true
# Test list
oac list
oac list --agents
oac list --local
oac list --global
# Test init (should ask local vs global)
cd /tmp/test-project
oac init developer
# Should prompt: "Install locally or globally?"
# Test approval system
cd /tmp/test-project
oac install opencode
# Should show file list and ask for confirmation
# Test YOLO mode
oac install opencode --yolo
# Should auto-confirm and report at end
# Test context resolution
oac context resolve 'core/standards/code-quality.md'
# Should show resolved path and priority
oac context list
# Should show all context files from all layers
oac context validate
# Should validate all context references
@nextsystems/oac/
├── bin/
│ └── oac.js # Updated entry point
├── src/
│ ├── cli/
│ │ ├── commands/
│ │ │ ├── configure.ts # NEW - Config management
│ │ │ ├── list.ts # NEW - List components
│ │ │ ├── init.ts # NEW - Initialize (asks local/global)
│ │ │ └── context.ts # NEW - Context commands (resolve, list, validate)
│ │ ├── config/
│ │ │ ├── manager.ts # NEW - Global + local merge
│ │ │ ├── schema.ts # NEW - Zod schema (approval + context config)
│ │ │ └── defaults.ts # NEW - Default config
│ │ └── index.ts # NEW - Commander setup (global flags)
│ ├── core/
│ │ ├── approval/
│ │ │ ├── manager.ts # NEW - Approval system (CRITICAL)
│ │ │ ├── strategies.ts # NEW - Conflict strategies
│ │ │ └── backup.ts # NEW - Backup management
│ │ ├── context/
│ │ │ ├── resolver.ts # NEW - 6-layer resolution (CRITICAL)
│ │ │ ├── locator.ts # NEW - Find context files
│ │ │ └── validator.ts # NEW - Validate references
│ │ └── installer/
│ │ └── location.ts # NEW - Detect local vs global
│ ├── types/
│ │ ├── config.ts # NEW - Config types
│ │ ├── approval.ts # NEW - Approval types
│ │ └── context.ts # NEW - Context types
│ └── utils/
│ ├── logger.ts # NEW - Logging
│ ├── prompts.ts # NEW - Interactive prompts
│ └── git.ts # NEW - Git detection
├── config/
│ └── oac.config.json # NEW - Default config
├── tsconfig.json # NEW
├── package.json # UPDATED
└── .opencode/ # EXISTING
// src/cli/config/schema.ts
import { z } from 'zod';
export const OACConfigSchema = z.object({
version: z.string(),
preferences: z.object({
defaultIDE: z.enum(['opencode', 'cursor', 'claude', 'windsurf']),
installLocation: z.enum(['local', 'global']),
autoUpdate: z.boolean(),
updateChannel: z.enum(['stable', 'beta', 'alpha'])
}),
ides: z.record(z.object({
enabled: z.boolean(),
path: z.string(),
profile: z.string()
})),
agents: z.object({
behavior: z.object({
approvalGates: z.boolean(),
contextLoading: z.enum(['lazy', 'eager']),
delegationThreshold: z.number()
}),
permissions: z.object({
bash: z.enum(['approve', 'auto', 'deny']),
write: z.enum(['approve', 'auto', 'deny']),
edit: z.enum(['approve', 'auto', 'deny']),
task: z.enum(['approve', 'auto', 'deny'])
})
}),
context: z.object({
locations: z.array(z.string()),
autoDiscover: z.boolean(),
cacheEnabled: z.boolean()
}),
registry: z.object({
source: z.string().url(),
localCache: z.string(),
updateInterval: z.number()
})
});
export type OACConfig = z.infer<typeof OACConfigSchema>;
{
"version": "1.0.0",
"preferences": {
"defaultIDE": "opencode",
"installLocation": "local",
"autoUpdate": false,
"updateChannel": "stable"
},
"ides": {
"opencode": {
"enabled": true,
"path": ".opencode",
"profile": "developer"
},
"cursor": {
"enabled": false,
"path": ".cursor",
"profile": "developer"
},
"claude": {
"enabled": false,
"path": ".claude",
"profile": "developer"
},
"windsurf": {
"enabled": false,
"path": ".windsurf",
"profile": "developer"
}
},
"agents": {
"behavior": {
"approvalGates": true,
"contextLoading": "lazy",
"delegationThreshold": 4
},
"permissions": {
"bash": "approve",
"write": "approve",
"edit": "approve",
"task": "approve"
}
},
"context": {
"locations": [
".opencode/context",
".claude/context",
"docs/context"
],
"autoDiscover": true,
"cacheEnabled": true
},
"registry": {
"source": "https://raw.githubusercontent.com/darrenhinde/OpenAgentsControl/main/registry.json",
"localCache": "~/.config/oac/registry.cache.json",
"updateInterval": 86400
}
}
// src/cli/config/manager.test.ts
import { describe, it, expect } from 'vitest';
import { ConfigManager } from './manager';
describe('ConfigManager', () => {
it('should load default config', async () => {
const manager = new ConfigManager();
const config = await manager.load();
expect(config.version).toBe('1.0.0');
});
it('should validate config schema', async () => {
const manager = new ConfigManager();
const valid = await manager.validate(mockConfig);
expect(valid).toBe(true);
});
it('should merge global and local configs', async () => {
const manager = new ConfigManager();
const config = await manager.load();
expect(config.preferences.defaultIDE).toBeDefined();
});
});
# Test CLI commands
npm run build
./bin/oac.js configure show
./bin/oac.js list
./bin/oac.js init developer
Create feature branch ✅
git checkout feature/oac-package-refactor
Set up TypeScript project
mkdir -p src/{cli/{commands,config},core,types,utils}
npm install dependencies
npx tsc --init
Implement Phase 1 tasks
Write tests
npm run test
Build and test locally
npm run build
npm pack
npm install -g ./nextsystems-oac-*.tgz
oac configure
Commit and push
git add .
git commit -m "feat(phase1): implement core CLI infrastructure"
git push
Context Files:
features/oac-package-refactor.md - Full feature contextcore-concepts/registry.md - Registry systemguides/npm-publishing.md - Publishing workflowExternal Docs:
GitHub:
feature/oac-package-refactorPhase 2: Registry & Component Management
Last Updated: 2026-02-14
Status: Ready to start Phase 1