recreate-fob 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/FOB-planner.md +52 -0
- package/.claude/agents/FOB-reviewer.md +61 -0
- package/.claude/commands/FOB/help.md +32 -0
- package/.claude/commands/FOB/scan.md +48 -0
- package/.claude/commands/FOB/status.md +47 -0
- package/.claude/skills/FOB-project-setup/skill.md +68 -0
- package/.codex/agents/FOB-planner.md +52 -0
- package/.codex/agents/FOB-reviewer.md +61 -0
- package/.codex/commands/FOB/help.md +32 -0
- package/.codex/commands/FOB/scan.md +48 -0
- package/.codex/commands/FOB/status.md +47 -0
- package/.codex/skills/FOB-project-setup/skill.md +68 -0
- package/.opencode/agents/FOB-planner.md +52 -0
- package/.opencode/agents/FOB-reviewer.md +61 -0
- package/.opencode/commands/FOB/help.md +32 -0
- package/.opencode/commands/FOB/scan.md +48 -0
- package/.opencode/commands/FOB/status.md +47 -0
- package/.opencode/skills/FOB-project-setup/skill.md +68 -0
- package/README.md +57 -0
- package/bin/install.js +316 -0
- package/forward-operating-base/VERSION +1 -0
- package/forward-operating-base/templates/project.md +44 -0
- package/package.json +31 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# FOB Reviewer Agent
|
|
2
|
+
|
|
3
|
+
You are a code review specialist focused on quality, maintainability, and best practices.
|
|
4
|
+
|
|
5
|
+
## Core Responsibilities
|
|
6
|
+
|
|
7
|
+
1. **Code Correctness**
|
|
8
|
+
- Verify logic is correct and handles all cases
|
|
9
|
+
- Check for potential bugs and edge cases
|
|
10
|
+
- Ensure error handling is appropriate
|
|
11
|
+
|
|
12
|
+
2. **Code Quality**
|
|
13
|
+
- Assess readability and maintainability
|
|
14
|
+
- Check for consistent coding style
|
|
15
|
+
- Identify opportunities for simplification
|
|
16
|
+
|
|
17
|
+
3. **Best Practices**
|
|
18
|
+
- Verify adherence to project conventions
|
|
19
|
+
- Check for security considerations
|
|
20
|
+
- Ensure performance is reasonable
|
|
21
|
+
|
|
22
|
+
## Review Checklist
|
|
23
|
+
|
|
24
|
+
When reviewing code, check:
|
|
25
|
+
|
|
26
|
+
- [ ] **Logic** - Does the code do what it's supposed to?
|
|
27
|
+
- [ ] **Edge Cases** - Are boundary conditions handled?
|
|
28
|
+
- [ ] **Error Handling** - Are errors caught and handled appropriately?
|
|
29
|
+
- [ ] **Readability** - Is the code easy to understand?
|
|
30
|
+
- [ ] **Naming** - Are variables and functions named clearly?
|
|
31
|
+
- [ ] **DRY** - Is there unnecessary duplication?
|
|
32
|
+
- [ ] **Security** - Are there any security concerns?
|
|
33
|
+
- [ ] **Performance** - Are there obvious performance issues?
|
|
34
|
+
|
|
35
|
+
## Output Format
|
|
36
|
+
|
|
37
|
+
When providing review feedback:
|
|
38
|
+
|
|
39
|
+
```markdown
|
|
40
|
+
## Summary
|
|
41
|
+
[Overall assessment: Approved / Needs Changes / Needs Discussion]
|
|
42
|
+
|
|
43
|
+
## Strengths
|
|
44
|
+
- [What's done well]
|
|
45
|
+
|
|
46
|
+
## Issues
|
|
47
|
+
1. **[Severity: Critical/Major/Minor]** - [File:Line]
|
|
48
|
+
[Description of the issue]
|
|
49
|
+
Suggestion: [How to fix]
|
|
50
|
+
|
|
51
|
+
## Suggestions
|
|
52
|
+
- [Optional improvements that aren't blocking]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Behavior Guidelines
|
|
56
|
+
|
|
57
|
+
- Be constructive, not critical
|
|
58
|
+
- Focus on the code, not the author
|
|
59
|
+
- Explain the "why" behind suggestions
|
|
60
|
+
- Prioritize issues by severity
|
|
61
|
+
- Acknowledge good work as well as issues
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: FOB:help
|
|
3
|
+
description: Display available Forward Operating Base commands
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FOB Help
|
|
7
|
+
|
|
8
|
+
Display all available Forward Operating Base (FOB) commands and their descriptions.
|
|
9
|
+
|
|
10
|
+
## Available Commands
|
|
11
|
+
|
|
12
|
+
| Command | Description |
|
|
13
|
+
|---------|-------------|
|
|
14
|
+
| `/FOB:help` | Display this help message |
|
|
15
|
+
| `/FOB:status` | Check FOB installation status and version |
|
|
16
|
+
| `/FOB:scan` | Scan project for FOB integration opportunities |
|
|
17
|
+
|
|
18
|
+
## Agents
|
|
19
|
+
|
|
20
|
+
The following FOB agents are available for use with the Task tool:
|
|
21
|
+
|
|
22
|
+
- **FOB-planner** - Strategic planning agent for project organization
|
|
23
|
+
- **FOB-reviewer** - Code review agent focused on quality and best practices
|
|
24
|
+
|
|
25
|
+
## Skills
|
|
26
|
+
|
|
27
|
+
- **FOB-project-setup** - Initialize projects with FOB-standard structure
|
|
28
|
+
|
|
29
|
+
## More Information
|
|
30
|
+
|
|
31
|
+
FOB assets are managed centrally and deployed via `npx recreate-fob`.
|
|
32
|
+
To update FOB assets, run the installer again in your project directory.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: FOB:scan
|
|
3
|
+
description: Scan project for FOB integration opportunities
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FOB Scan
|
|
7
|
+
|
|
8
|
+
Analyze the current project and suggest FOB integrations that could improve workflow.
|
|
9
|
+
|
|
10
|
+
## Instructions
|
|
11
|
+
|
|
12
|
+
1. **Scan Project Structure**
|
|
13
|
+
- Look for existing `.claude/`, `.opencode/`, `.codex/` directories
|
|
14
|
+
- Identify the project type (Node.js, Python, Go, etc.)
|
|
15
|
+
- Check for existing commands, agents, and skills
|
|
16
|
+
|
|
17
|
+
2. **Analyze Existing Configuration**
|
|
18
|
+
- Read any existing `@claude.md` or similar config files
|
|
19
|
+
- Identify custom commands that might benefit from FOB patterns
|
|
20
|
+
- Look for repeated patterns that could be extracted into agents
|
|
21
|
+
|
|
22
|
+
3. **Generate Recommendations**
|
|
23
|
+
Based on the project type and existing setup, suggest:
|
|
24
|
+
- FOB commands that could help with common tasks
|
|
25
|
+
- Agents that could automate recurring workflows
|
|
26
|
+
- Skills that could streamline project operations
|
|
27
|
+
|
|
28
|
+
## Output Format
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
FOB Scan Results
|
|
32
|
+
================
|
|
33
|
+
|
|
34
|
+
Project Type: [detected type]
|
|
35
|
+
Existing Frameworks: [list of .claude, .opencode, .codex if present]
|
|
36
|
+
|
|
37
|
+
Recommendations:
|
|
38
|
+
1. [Recommendation with explanation]
|
|
39
|
+
2. [Recommendation with explanation]
|
|
40
|
+
3. [Recommendation with explanation]
|
|
41
|
+
|
|
42
|
+
Quick Start:
|
|
43
|
+
Run: npx recreate-fob --local
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Reference
|
|
47
|
+
|
|
48
|
+
For available FOB assets, see: @~/.claude/forward-operating-base/templates/
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: FOB:status
|
|
3
|
+
description: Check Forward Operating Base installation status and version
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FOB Status
|
|
7
|
+
|
|
8
|
+
Check the current Forward Operating Base installation status and version.
|
|
9
|
+
|
|
10
|
+
## Instructions
|
|
11
|
+
|
|
12
|
+
1. Look for `.fob-version` file in the project root to determine installed version
|
|
13
|
+
2. List all FOB-prefixed commands in `.claude/commands/FOB/`
|
|
14
|
+
3. List all FOB-prefixed agents (files matching `FOB-*.md` in `.claude/agents/`)
|
|
15
|
+
4. List all FOB-prefixed skills (directories matching `FOB-*` in `.claude/skills/`)
|
|
16
|
+
5. Check if `forward-operating-base/` shared assets directory exists
|
|
17
|
+
|
|
18
|
+
## Output Format
|
|
19
|
+
|
|
20
|
+
Provide a structured status report:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
FOB Status Report
|
|
24
|
+
=================
|
|
25
|
+
Version: [version from .fob-version or "Not installed"]
|
|
26
|
+
|
|
27
|
+
Commands:
|
|
28
|
+
- FOB:help
|
|
29
|
+
- FOB:status
|
|
30
|
+
- FOB:scan
|
|
31
|
+
|
|
32
|
+
Agents:
|
|
33
|
+
- FOB-planner
|
|
34
|
+
- FOB-reviewer
|
|
35
|
+
|
|
36
|
+
Skills:
|
|
37
|
+
- FOB-project-setup
|
|
38
|
+
|
|
39
|
+
Shared Assets: [Installed / Not found]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Troubleshooting
|
|
43
|
+
|
|
44
|
+
If FOB is not installed or partially installed, suggest running:
|
|
45
|
+
```bash
|
|
46
|
+
npx recreate-fob --local
|
|
47
|
+
```
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: FOB-project-setup
|
|
3
|
+
description: Initialize projects with FOB-standard structure
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# FOB Project Setup Skill
|
|
7
|
+
|
|
8
|
+
This skill helps initialize new projects with a standardized FOB structure and configuration.
|
|
9
|
+
|
|
10
|
+
## Trigger
|
|
11
|
+
|
|
12
|
+
Activated by mentioning "FOB setup", "FOB init", or "initialize FOB".
|
|
13
|
+
|
|
14
|
+
## Process
|
|
15
|
+
|
|
16
|
+
### 1. Analyze Project Type
|
|
17
|
+
|
|
18
|
+
First, detect the project type and existing configuration:
|
|
19
|
+
- Check for package.json (Node.js)
|
|
20
|
+
- Check for requirements.txt or pyproject.toml (Python)
|
|
21
|
+
- Check for go.mod (Go)
|
|
22
|
+
- Check for Cargo.toml (Rust)
|
|
23
|
+
- Look for existing .claude/, .opencode/, .codex/ directories
|
|
24
|
+
|
|
25
|
+
### 2. Create Structure
|
|
26
|
+
|
|
27
|
+
Based on the project type, create appropriate directories:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
project/
|
|
31
|
+
├── .claude/
|
|
32
|
+
│ ├── commands/
|
|
33
|
+
│ │ └── [project-specific commands]
|
|
34
|
+
│ └── agents/
|
|
35
|
+
│ └── [project-specific agents]
|
|
36
|
+
└── forward-operating-base/ (if not already present)
|
|
37
|
+
└── [shared assets]
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 3. Configure Integration
|
|
41
|
+
|
|
42
|
+
- Create or update @claude.md with project context
|
|
43
|
+
- Add project-specific commands based on detected framework
|
|
44
|
+
- Configure any relevant hooks
|
|
45
|
+
|
|
46
|
+
## Output
|
|
47
|
+
|
|
48
|
+
After setup, provide a summary:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
FOB Project Setup Complete
|
|
52
|
+
==========================
|
|
53
|
+
|
|
54
|
+
Created:
|
|
55
|
+
- .claude/commands/
|
|
56
|
+
- .claude/agents/
|
|
57
|
+
|
|
58
|
+
Detected: [project type]
|
|
59
|
+
|
|
60
|
+
Next Steps:
|
|
61
|
+
1. Run /FOB:help to see available commands
|
|
62
|
+
2. Create project-specific commands in .claude/commands/
|
|
63
|
+
3. Add project context to @claude.md
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Templates
|
|
67
|
+
|
|
68
|
+
Reference: @~/forward-operating-base/templates/project.md
|
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# recreate-fob
|
|
2
|
+
|
|
3
|
+
Deploy Forward Operating Base (FOB) assets for AI coding assistants. This package installs skills, agents, and configuration files that enhance your AI coding workflow.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx recreate-fob --local
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This installs FOB assets to your current project directory.
|
|
12
|
+
|
|
13
|
+
### Options
|
|
14
|
+
|
|
15
|
+
- `--local` - Install to the current directory (default)
|
|
16
|
+
- `--global` - Install to your home directory (`~/.claude/`)
|
|
17
|
+
- `--help` - Show help information
|
|
18
|
+
|
|
19
|
+
## What Gets Installed
|
|
20
|
+
|
|
21
|
+
The package deploys configuration files for multiple AI coding assistants:
|
|
22
|
+
|
|
23
|
+
- **Claude Code** (`.claude/`) - Skills and agent configurations
|
|
24
|
+
- **OpenCode** (`.opencode/`) - Agent definitions
|
|
25
|
+
- **Codex** (`.codex/`) - Instructions and agents
|
|
26
|
+
|
|
27
|
+
Plus a shared `forward-operating-base/` directory containing reusable assets.
|
|
28
|
+
|
|
29
|
+
## Available Commands
|
|
30
|
+
|
|
31
|
+
Once installed, you can use these slash commands in Claude Code:
|
|
32
|
+
|
|
33
|
+
| Command | Description |
|
|
34
|
+
|---------|-------------|
|
|
35
|
+
| `/FOB:help` | Show available FOB commands and agents |
|
|
36
|
+
| `/FOB:status` | Check FOB installation status |
|
|
37
|
+
| `/FOB:scan` | Scan project for potential improvements |
|
|
38
|
+
|
|
39
|
+
## Available Agents
|
|
40
|
+
|
|
41
|
+
| Agent | Description |
|
|
42
|
+
|-------|-------------|
|
|
43
|
+
| `FOB-planner` | Strategic planning agent for complex tasks |
|
|
44
|
+
| `FOB-reviewer` | Code review agent with structured feedback |
|
|
45
|
+
|
|
46
|
+
## How Updates Work
|
|
47
|
+
|
|
48
|
+
When you run `npx recreate-fob` again:
|
|
49
|
+
|
|
50
|
+
- **FOB-prefixed items** are overwritten with the latest versions
|
|
51
|
+
- **User content** (your custom skills, agents, settings) is preserved
|
|
52
|
+
|
|
53
|
+
This allows you to receive updates while keeping your customizations intact.
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
MIT
|
package/bin/install.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const readline = require('readline');
|
|
7
|
+
|
|
8
|
+
// Colors for terminal output
|
|
9
|
+
const cyan = '\x1b[36m';
|
|
10
|
+
const green = '\x1b[32m';
|
|
11
|
+
const yellow = '\x1b[33m';
|
|
12
|
+
const dim = '\x1b[2m';
|
|
13
|
+
const reset = '\x1b[0m';
|
|
14
|
+
|
|
15
|
+
// Get version from package.json
|
|
16
|
+
const pkg = require('../package.json');
|
|
17
|
+
|
|
18
|
+
const banner = `
|
|
19
|
+
${cyan} ███████╗ ██████╗ ██████╗
|
|
20
|
+
██╔════╝██╔═══██╗██╔══██╗
|
|
21
|
+
█████╗ ██║ ██║██████╔╝
|
|
22
|
+
██╔══╝ ██║ ██║██╔══██╗
|
|
23
|
+
██║ ╚██████╔╝██████╔╝
|
|
24
|
+
╚═╝ ╚═════╝ ╚═════╝${reset}
|
|
25
|
+
|
|
26
|
+
Forward Operating Base ${dim}v${pkg.version}${reset}
|
|
27
|
+
Deploy AI assistant configurations across projects.
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
// Configuration
|
|
31
|
+
const FOB_PREFIX = 'FOB';
|
|
32
|
+
const FRAMEWORKS = [
|
|
33
|
+
{ name: 'claude', dir: '.claude' },
|
|
34
|
+
{ name: 'opencode', dir: '.opencode' },
|
|
35
|
+
{ name: 'codex', dir: '.codex' }
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
// Parse command line arguments
|
|
39
|
+
const args = process.argv.slice(2);
|
|
40
|
+
const hasGlobal = args.includes('--global') || args.includes('-g');
|
|
41
|
+
const hasLocal = args.includes('--local') || args.includes('-l');
|
|
42
|
+
const hasHelp = args.includes('--help') || args.includes('-h');
|
|
43
|
+
|
|
44
|
+
console.log(banner);
|
|
45
|
+
|
|
46
|
+
// Show help if requested
|
|
47
|
+
if (hasHelp) {
|
|
48
|
+
console.log(` ${yellow}Usage:${reset} npx recreate-fob [options]
|
|
49
|
+
|
|
50
|
+
${yellow}Options:${reset}
|
|
51
|
+
${cyan}-g, --global${reset} Install globally (to ~/.<framework> directories)
|
|
52
|
+
${cyan}-l, --local${reset} Install locally (to ./<framework> in current directory)
|
|
53
|
+
${cyan}-h, --help${reset} Show this help message
|
|
54
|
+
|
|
55
|
+
${yellow}Examples:${reset}
|
|
56
|
+
${dim}# Install to current project only${reset}
|
|
57
|
+
npx recreate-fob --local
|
|
58
|
+
|
|
59
|
+
${dim}# Install globally (available in all projects)${reset}
|
|
60
|
+
npx recreate-fob --global
|
|
61
|
+
|
|
62
|
+
${yellow}Supported Frameworks:${reset}
|
|
63
|
+
.claude Claude Code
|
|
64
|
+
.opencode OpenCode CLI
|
|
65
|
+
.codex Codex CLI
|
|
66
|
+
`);
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Expand ~ to home directory
|
|
72
|
+
*/
|
|
73
|
+
function expandTilde(filePath) {
|
|
74
|
+
if (filePath && filePath.startsWith('~/')) {
|
|
75
|
+
return path.join(os.homedir(), filePath.slice(2));
|
|
76
|
+
}
|
|
77
|
+
return filePath;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Replace path placeholders in markdown content
|
|
82
|
+
*/
|
|
83
|
+
function replacePathPlaceholders(content, pathPrefix) {
|
|
84
|
+
return content
|
|
85
|
+
.replace(/@~\/.claude\//g, pathPrefix + '.claude/')
|
|
86
|
+
.replace(/@~\/.opencode\//g, pathPrefix + '.opencode/')
|
|
87
|
+
.replace(/@~\/.codex\//g, pathPrefix + '.codex/')
|
|
88
|
+
.replace(/@~\/forward-operating-base\//g, pathPrefix + 'forward-operating-base/');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Copy a file with path replacements for .md files
|
|
93
|
+
*/
|
|
94
|
+
function copyFileWithReplacements(srcPath, destPath, pathPrefix) {
|
|
95
|
+
const destDir = path.dirname(destPath);
|
|
96
|
+
if (!fs.existsSync(destDir)) {
|
|
97
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (srcPath.endsWith('.md')) {
|
|
101
|
+
let content = fs.readFileSync(srcPath, 'utf8');
|
|
102
|
+
content = replacePathPlaceholders(content, pathPrefix);
|
|
103
|
+
fs.writeFileSync(destPath, content);
|
|
104
|
+
} else {
|
|
105
|
+
fs.copyFileSync(srcPath, destPath);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Recursively copy directory with path replacement
|
|
111
|
+
* Deletes existing destDir first to remove orphaned files
|
|
112
|
+
*/
|
|
113
|
+
function copyWithPathReplacement(srcDir, destDir, pathPrefix) {
|
|
114
|
+
// Clean install: remove existing destination
|
|
115
|
+
if (fs.existsSync(destDir)) {
|
|
116
|
+
fs.rmSync(destDir, { recursive: true });
|
|
117
|
+
}
|
|
118
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
119
|
+
|
|
120
|
+
const entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
121
|
+
for (const entry of entries) {
|
|
122
|
+
const srcPath = path.join(srcDir, entry.name);
|
|
123
|
+
const destPath = path.join(destDir, entry.name);
|
|
124
|
+
|
|
125
|
+
if (entry.isDirectory()) {
|
|
126
|
+
copyWithPathReplacement(srcPath, destPath, pathPrefix);
|
|
127
|
+
} else if (!entry.name.startsWith('.DS_Store')) {
|
|
128
|
+
copyFileWithReplacements(srcPath, destPath, pathPrefix);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Delete files/directories matching a prefix pattern
|
|
135
|
+
*/
|
|
136
|
+
function deleteMatchingItems(dir, prefix) {
|
|
137
|
+
if (!fs.existsSync(dir)) return;
|
|
138
|
+
|
|
139
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
140
|
+
for (const entry of entries) {
|
|
141
|
+
if (entry.name.startsWith(prefix)) {
|
|
142
|
+
const fullPath = path.join(dir, entry.name);
|
|
143
|
+
if (entry.isDirectory()) {
|
|
144
|
+
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
145
|
+
} else {
|
|
146
|
+
fs.unlinkSync(fullPath);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Copy files from source to dest, preserving existing non-matching files
|
|
154
|
+
*/
|
|
155
|
+
function copyFilesPreserving(srcDir, destDir, pathPrefix) {
|
|
156
|
+
if (!fs.existsSync(srcDir)) return;
|
|
157
|
+
|
|
158
|
+
if (!fs.existsSync(destDir)) {
|
|
159
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
163
|
+
for (const entry of entries) {
|
|
164
|
+
const srcPath = path.join(srcDir, entry.name);
|
|
165
|
+
const destPath = path.join(destDir, entry.name);
|
|
166
|
+
|
|
167
|
+
if (entry.isDirectory()) {
|
|
168
|
+
copyWithPathReplacement(srcPath, destPath, pathPrefix);
|
|
169
|
+
} else if (entry.isFile() && !entry.name.startsWith('.DS_Store')) {
|
|
170
|
+
copyFileWithReplacements(srcPath, destPath, pathPrefix);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Install assets for a single framework
|
|
177
|
+
*/
|
|
178
|
+
function installFramework(framework, targetRoot, pathPrefix) {
|
|
179
|
+
const src = path.join(__dirname, '..');
|
|
180
|
+
const srcFramework = path.join(src, framework.dir);
|
|
181
|
+
const destFramework = path.join(targetRoot, framework.dir);
|
|
182
|
+
|
|
183
|
+
// Check if we have source assets for this framework
|
|
184
|
+
if (!fs.existsSync(srcFramework)) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
console.log(`\n Installing ${cyan}${framework.name}${reset} assets...`);
|
|
189
|
+
|
|
190
|
+
// Ensure target framework directory exists
|
|
191
|
+
if (!fs.existsSync(destFramework)) {
|
|
192
|
+
fs.mkdirSync(destFramework, { recursive: true });
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 1. Commands: Full wipe of FOB/ subdirectory
|
|
196
|
+
const srcCommands = path.join(srcFramework, 'commands', FOB_PREFIX);
|
|
197
|
+
const destCommands = path.join(destFramework, 'commands', FOB_PREFIX);
|
|
198
|
+
if (fs.existsSync(srcCommands)) {
|
|
199
|
+
copyWithPathReplacement(srcCommands, destCommands, pathPrefix);
|
|
200
|
+
console.log(` ${green}✓${reset} commands/${FOB_PREFIX}/`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 2. Agents: Selective deletion (only FOB-*.md files)
|
|
204
|
+
const srcAgents = path.join(srcFramework, 'agents');
|
|
205
|
+
const destAgents = path.join(destFramework, 'agents');
|
|
206
|
+
if (fs.existsSync(srcAgents)) {
|
|
207
|
+
// Delete existing FOB-*.md agents
|
|
208
|
+
deleteMatchingItems(destAgents, `${FOB_PREFIX}-`);
|
|
209
|
+
// Copy new agents
|
|
210
|
+
copyFilesPreserving(srcAgents, destAgents, pathPrefix);
|
|
211
|
+
console.log(` ${green}✓${reset} agents/ (selective: ${FOB_PREFIX}-*)`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// 3. Skills: Selective deletion (only FOB-* directories)
|
|
215
|
+
const srcSkills = path.join(srcFramework, 'skills');
|
|
216
|
+
const destSkills = path.join(destFramework, 'skills');
|
|
217
|
+
if (fs.existsSync(srcSkills)) {
|
|
218
|
+
// Delete existing FOB-* skill directories
|
|
219
|
+
deleteMatchingItems(destSkills, `${FOB_PREFIX}-`);
|
|
220
|
+
// Copy new skills
|
|
221
|
+
copyFilesPreserving(srcSkills, destSkills, pathPrefix);
|
|
222
|
+
console.log(` ${green}✓${reset} skills/ (selective: ${FOB_PREFIX}-*)`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Install shared forward-operating-base assets
|
|
230
|
+
*/
|
|
231
|
+
function installSharedAssets(targetRoot, pathPrefix) {
|
|
232
|
+
const src = path.join(__dirname, '..');
|
|
233
|
+
const srcFob = path.join(src, 'forward-operating-base');
|
|
234
|
+
const destFob = path.join(targetRoot, 'forward-operating-base');
|
|
235
|
+
|
|
236
|
+
if (fs.existsSync(srcFob)) {
|
|
237
|
+
console.log(`\n Installing ${cyan}shared assets${reset}...`);
|
|
238
|
+
copyWithPathReplacement(srcFob, destFob, pathPrefix);
|
|
239
|
+
console.log(` ${green}✓${reset} forward-operating-base/`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Main installation function
|
|
245
|
+
*/
|
|
246
|
+
function install(isGlobal) {
|
|
247
|
+
const targetRoot = isGlobal ? os.homedir() : process.cwd();
|
|
248
|
+
const pathPrefix = isGlobal ? '~/' : './';
|
|
249
|
+
|
|
250
|
+
const locationLabel = isGlobal
|
|
251
|
+
? `~/ ${dim}(global)${reset}`
|
|
252
|
+
: `./ ${dim}(local)${reset}`;
|
|
253
|
+
|
|
254
|
+
console.log(` Installing to ${cyan}${locationLabel}${reset}`);
|
|
255
|
+
|
|
256
|
+
let installedCount = 0;
|
|
257
|
+
|
|
258
|
+
// Install each framework
|
|
259
|
+
for (const framework of FRAMEWORKS) {
|
|
260
|
+
if (installFramework(framework, targetRoot, pathPrefix)) {
|
|
261
|
+
installedCount++;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Install shared assets
|
|
266
|
+
installSharedAssets(targetRoot, pathPrefix);
|
|
267
|
+
|
|
268
|
+
// Write version marker file
|
|
269
|
+
const versionPath = path.join(targetRoot, '.fob-version');
|
|
270
|
+
fs.writeFileSync(versionPath, pkg.version);
|
|
271
|
+
console.log(`\n ${green}✓${reset} .fob-version (${pkg.version})`);
|
|
272
|
+
|
|
273
|
+
console.log(`
|
|
274
|
+
${green} ════════════════════════════════════════${reset}
|
|
275
|
+
${green}Done!${reset} FOB v${pkg.version} installed successfully.
|
|
276
|
+
|
|
277
|
+
Installed to ${installedCount} framework(s).
|
|
278
|
+
Run ${cyan}/FOB:help${reset} in your AI assistant to get started.
|
|
279
|
+
${green} ════════════════════════════════════════${reset}
|
|
280
|
+
`);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Prompt user for installation location
|
|
285
|
+
*/
|
|
286
|
+
function promptLocation() {
|
|
287
|
+
const rl = readline.createInterface({
|
|
288
|
+
input: process.stdin,
|
|
289
|
+
output: process.stdout
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
console.log(` ${yellow}Where would you like to install?${reset}
|
|
293
|
+
|
|
294
|
+
${cyan}1${reset}) Local ${dim}(./)${reset} - this project only
|
|
295
|
+
${cyan}2${reset}) Global ${dim}(~/)${reset} - available in all projects
|
|
296
|
+
`);
|
|
297
|
+
|
|
298
|
+
rl.question(` Choice ${dim}[1]${reset}: `, (answer) => {
|
|
299
|
+
rl.close();
|
|
300
|
+
const choice = answer.trim() || '1';
|
|
301
|
+
const isGlobal = choice === '2';
|
|
302
|
+
install(isGlobal);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Main execution
|
|
307
|
+
if (hasGlobal && hasLocal) {
|
|
308
|
+
console.error(` ${yellow}Cannot specify both --global and --local${reset}`);
|
|
309
|
+
process.exit(1);
|
|
310
|
+
} else if (hasGlobal) {
|
|
311
|
+
install(true);
|
|
312
|
+
} else if (hasLocal) {
|
|
313
|
+
install(false);
|
|
314
|
+
} else {
|
|
315
|
+
promptLocation();
|
|
316
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.0.0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Project Template
|
|
2
|
+
|
|
3
|
+
This template provides a starting structure for new projects using FOB.
|
|
4
|
+
|
|
5
|
+
## Project Information
|
|
6
|
+
|
|
7
|
+
- **Name**: [Project Name]
|
|
8
|
+
- **Type**: [Node.js / Python / Go / Other]
|
|
9
|
+
- **Description**: [Brief description of the project]
|
|
10
|
+
|
|
11
|
+
## Directory Structure
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
project/
|
|
15
|
+
├── .claude/
|
|
16
|
+
│ ├── commands/
|
|
17
|
+
│ │ └── FOB/ # FOB-managed commands
|
|
18
|
+
│ │ └── [custom]/ # Project-specific commands
|
|
19
|
+
│ ├── agents/
|
|
20
|
+
│ │ └── FOB-*.md # FOB-managed agents
|
|
21
|
+
│ │ └── [custom].md # Project-specific agents
|
|
22
|
+
│ └── skills/
|
|
23
|
+
│ └── FOB-*/ # FOB-managed skills
|
|
24
|
+
├── forward-operating-base/
|
|
25
|
+
│ └── templates/ # Shared templates
|
|
26
|
+
└── src/ # Source code
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Getting Started
|
|
30
|
+
|
|
31
|
+
1. Run `npx recreate-fob --local` to install FOB assets
|
|
32
|
+
2. Customize `.claude/@claude.md` with project context
|
|
33
|
+
3. Add project-specific commands as needed
|
|
34
|
+
|
|
35
|
+
## Available Commands
|
|
36
|
+
|
|
37
|
+
- `/FOB:help` - Display available FOB commands
|
|
38
|
+
- `/FOB:status` - Check installation status
|
|
39
|
+
- `/FOB:scan` - Scan for integration opportunities
|
|
40
|
+
|
|
41
|
+
## Available Agents
|
|
42
|
+
|
|
43
|
+
- **FOB-planner** - For task planning and breakdown
|
|
44
|
+
- **FOB-reviewer** - For code review and quality checks
|