glooit 0.5.1 โ 0.5.3
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/README.md +173 -37
- package/bin/glooit-linux +0 -0
- package/bin/glooit-macos +0 -0
- package/bin/glooit-windows.exe +0 -0
- package/dist/agents/distributor.d.ts +2 -0
- package/dist/agents/index.d.ts +5 -5
- package/dist/agents/writers/index.d.ts +2 -2
- package/dist/cli/index.js +102 -140
- package/dist/core/gitignore.d.ts +2 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/index.js +111 -139
- package/dist/types/index.d.ts +8 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,11 +7,15 @@
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
# Install
|
|
11
|
-
npm install -g
|
|
10
|
+
# Install
|
|
11
|
+
npm install -g glooit
|
|
12
|
+
bun install -g glooit
|
|
13
|
+
pnpm install -g glooit
|
|
12
14
|
|
|
13
|
-
#
|
|
14
|
-
npx
|
|
15
|
+
# Run
|
|
16
|
+
npx glooit init
|
|
17
|
+
bunx glooit init
|
|
18
|
+
pnpx glooit init
|
|
15
19
|
```
|
|
16
20
|
|
|
17
21
|
## Basic Usage
|
|
@@ -30,9 +34,9 @@ import { Config } from 'glooit';
|
|
|
30
34
|
export default {
|
|
31
35
|
rules: [
|
|
32
36
|
{
|
|
33
|
-
file: '
|
|
37
|
+
file: 'main.md',
|
|
34
38
|
to: './',
|
|
35
|
-
targets: ['claude', 'cursor']
|
|
39
|
+
targets: ['claude', 'cursor', 'codex']
|
|
36
40
|
}
|
|
37
41
|
]
|
|
38
42
|
} satisfies Config;
|
|
@@ -45,8 +49,10 @@ glooit sync
|
|
|
45
49
|
```
|
|
46
50
|
|
|
47
51
|
This automatically creates:
|
|
52
|
+
|
|
48
53
|
- `CLAUDE.md` (for Claude Code)
|
|
49
|
-
- `.cursor/rules/
|
|
54
|
+
- `.cursor/rules/main.md` (for Cursor)
|
|
55
|
+
- `AGENTS.md` (for Codex)
|
|
50
56
|
|
|
51
57
|
### 3. Add MCP Configurations
|
|
52
58
|
|
|
@@ -73,36 +79,179 @@ export default {
|
|
|
73
79
|
|
|
74
80
|
### Supported Agents
|
|
75
81
|
|
|
76
|
-
- **Claude Code
|
|
77
|
-
- **Cursor
|
|
78
|
-
- **Roo Code/Cline
|
|
82
|
+
- **Claude Code**
|
|
83
|
+
- **Cursor**
|
|
84
|
+
- **Roo Code/Cline**
|
|
85
|
+
- **Codex**
|
|
86
|
+
- **Generic**
|
|
79
87
|
|
|
80
|
-
###
|
|
88
|
+
### Full Configuration
|
|
81
89
|
|
|
82
90
|
```typescript
|
|
83
|
-
import {
|
|
91
|
+
import { defineRules } from 'glooit';
|
|
84
92
|
|
|
85
|
-
export default {
|
|
93
|
+
export default defineRules({
|
|
86
94
|
configDir: '.glooit',
|
|
95
|
+
targets: ['claude', 'cursor'],
|
|
87
96
|
rules: [
|
|
88
97
|
{
|
|
89
|
-
|
|
98
|
+
name: 'main',
|
|
99
|
+
file: '.glooit/main.md',
|
|
90
100
|
to: './',
|
|
91
|
-
targets: ['claude', 'cursor'
|
|
101
|
+
targets: ['claude', 'cursor']
|
|
92
102
|
}
|
|
93
103
|
],
|
|
104
|
+
mcps: [],
|
|
105
|
+
mergeMcps: true,
|
|
106
|
+
backup: {
|
|
107
|
+
enabled: true,
|
|
108
|
+
retention: 10
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Advanced Usage
|
|
114
|
+
|
|
115
|
+
### Custom File Destinations
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
export default defineRules({
|
|
119
|
+
rules: [
|
|
120
|
+
{
|
|
121
|
+
name: 'backend-rules',
|
|
122
|
+
file: '.glooit/backend.md',
|
|
123
|
+
to: './',
|
|
124
|
+
targets: [
|
|
125
|
+
'claude',
|
|
126
|
+
{ name: 'cursor', to: './backend/.cursor/rules/backend.md' },
|
|
127
|
+
{ name: 'generic', to: './docs/backend-standards.md' }
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
]
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Hooks (Before & After Sync)
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
import { defineRules, hooks } from 'glooit';
|
|
138
|
+
|
|
139
|
+
export default defineRules({
|
|
140
|
+
rules: [/* your rules */],
|
|
141
|
+
hooks: {
|
|
142
|
+
before: [
|
|
143
|
+
async ({ config }) => {
|
|
144
|
+
console.log('๐ Starting sync...');
|
|
145
|
+
// Run tests, validate env, etc.
|
|
146
|
+
}
|
|
147
|
+
],
|
|
148
|
+
after: [
|
|
149
|
+
async (context) => {
|
|
150
|
+
console.log('โ
Sync complete!');
|
|
151
|
+
// Commit changes, notify team, etc.
|
|
152
|
+
return `Synced ${context.rule.name} successfully`;
|
|
153
|
+
},
|
|
154
|
+
hooks.addTimestamp,
|
|
155
|
+
hooks.replaceEnv
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Built-in Hooks
|
|
162
|
+
|
|
163
|
+
glooit comes with handy hooks to supercharge your sync process:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { defineRules, hooks } from 'glooit';
|
|
167
|
+
|
|
168
|
+
export default defineRules({
|
|
169
|
+
rules: [/* your rules */],
|
|
170
|
+
hooks: {
|
|
171
|
+
after: [
|
|
172
|
+
hooks.addTimestamp,
|
|
173
|
+
hooks.replaceEnv,
|
|
174
|
+
hooks.replaceStructure,
|
|
175
|
+
hooks.compact()
|
|
176
|
+
]
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**๐ `addTimestamp`** - Replace `__TIMESTAMP__` with current date/time
|
|
182
|
+
```markdown
|
|
183
|
+
Last updated: __TIMESTAMP__
|
|
184
|
+
<!-- Becomes: Last updated: December 24, 2024, 03:30 PM -->
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**๐ `replaceEnv`** - Replace `__ENV_VAR__` patterns with environment variables
|
|
188
|
+
```markdown
|
|
189
|
+
Database: __ENV_DATABASE_URL__
|
|
190
|
+
API Key: __ENV_API_KEY__
|
|
191
|
+
<!-- Uses your actual env vars -->
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**๐ `replaceStructure`** - Replace `__STRUCTURE__` with project tree
|
|
195
|
+
```markdown
|
|
196
|
+
Project structure:
|
|
197
|
+
__STRUCTURE__
|
|
198
|
+
<!-- Becomes a nice ASCII tree of your project -->
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**๐๏ธ `compact`** - Clean up and compress your markdown
|
|
202
|
+
```typescript
|
|
203
|
+
hooks.compact({
|
|
204
|
+
maxConsecutiveNewlines: 2,
|
|
205
|
+
removeFillerWords: true, // Removes "basically", "literally", etc.
|
|
206
|
+
compactLists: true // Tightens up list spacing
|
|
207
|
+
})
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### MCP Configuration
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
export default defineRules({
|
|
214
|
+
rules: [/* your rules */],
|
|
94
215
|
mcps: [
|
|
95
216
|
{
|
|
96
|
-
name: '
|
|
217
|
+
name: 'filesystem',
|
|
97
218
|
config: {
|
|
98
219
|
command: 'npx',
|
|
99
|
-
args: ['
|
|
220
|
+
args: ['@modelcontextprotocol/server-filesystem', process.cwd()]
|
|
100
221
|
},
|
|
101
222
|
targets: ['claude']
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: 'postgres',
|
|
226
|
+
config: {
|
|
227
|
+
command: 'uvx',
|
|
228
|
+
args: ['mcp-server-postgres'],
|
|
229
|
+
env: { DATABASE_URL: process.env.DATABASE_URL }
|
|
230
|
+
},
|
|
231
|
+
targets: ['claude', 'cursor']
|
|
102
232
|
}
|
|
103
|
-
]
|
|
104
|
-
|
|
105
|
-
|
|
233
|
+
]
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Monorepos & AGENTS.md
|
|
238
|
+
|
|
239
|
+
When using `AGENTS.md` in subdirectories, Cursor automatically detects them - no need to enable Cursor for those specific paths. Perfect for monorepos where different services need different rules.
|
|
240
|
+
|
|
241
|
+
### File Formats by Project Type
|
|
242
|
+
|
|
243
|
+
**JavaScript/TypeScript projects:**
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
// glooit.config.ts - with TypeScript support
|
|
247
|
+
export default defineRules({ /* config */ });
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Non-JS projects:**
|
|
251
|
+
|
|
252
|
+
```javascript
|
|
253
|
+
// glooit.config.js - plain JavaScript / typescript
|
|
254
|
+
export default { /* config */ };
|
|
106
255
|
```
|
|
107
256
|
|
|
108
257
|
## Commands
|
|
@@ -120,25 +269,12 @@ glooit backup list # List backups
|
|
|
120
269
|
|
|
121
270
|
- ๐ **Multi-platform sync** - Works with all major AI coding assistants
|
|
122
271
|
- ๐ฆ **MCP support** - Model Context Protocol configuration management
|
|
123
|
-
- ๐ฏ **Selective targeting** - Choose which agents get which rules
|
|
272
|
+
- ๐ฏ **Selective targeting** - Choose which agents get which rules and wht folders, perfect for complex projects & monorepos
|
|
124
273
|
- ๐ **Backup system** - Automatic backups before changes
|
|
125
274
|
- ๐งน **Clean management** - Easy cleanup and reset options
|
|
126
|
-
-
|
|
127
|
-
|
|
128
|
-
## Installation
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
# NPM
|
|
132
|
-
npm install -g glooit
|
|
133
|
-
|
|
134
|
-
# Bun
|
|
135
|
-
bun install -g glooit
|
|
136
|
-
|
|
137
|
-
# Direct execution
|
|
138
|
-
npx glooitit init
|
|
139
|
-
bunx glooitit sync
|
|
140
|
-
```
|
|
275
|
+
- ๐ **Auto .gitignore** - Automatically manages generated files in .gitignore
|
|
276
|
+
- โก **Fast** - Built with Bun for.... you know... bun?
|
|
141
277
|
|
|
142
278
|
## License
|
|
143
279
|
|
|
144
|
-
MIT
|
|
280
|
+
MIT
|
package/bin/glooit-linux
CHANGED
|
Binary file
|
package/bin/glooit-macos
CHANGED
|
Binary file
|
package/bin/glooit-windows.exe
CHANGED
|
Binary file
|
package/dist/agents/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const AGENT_MAPPINGS: Record<
|
|
3
|
-
export declare function getAgentPath(agent:
|
|
4
|
-
export declare function getAgentDirectory(agent:
|
|
5
|
-
export declare function getAgentMcpPath(agent:
|
|
1
|
+
import type { AgentName, AgentMapping } from '../types';
|
|
2
|
+
export declare const AGENT_MAPPINGS: Record<AgentName, AgentMapping>;
|
|
3
|
+
export declare function getAgentPath(agent: AgentName, name?: string): string;
|
|
4
|
+
export declare function getAgentDirectory(agent: AgentName): string | undefined;
|
|
5
|
+
export declare function getAgentMcpPath(agent: AgentName): string;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AgentName, Rule, ResolvedMcp } from '../../types';
|
|
2
2
|
export interface AgentWriter {
|
|
3
3
|
formatContent(content: string, rule: Rule): string;
|
|
4
4
|
formatMcp?(mcp: ResolvedMcp, merge: boolean): string;
|
|
5
5
|
}
|
|
6
6
|
export declare class AgentWriterFactory {
|
|
7
|
-
static createWriter(agent:
|
|
7
|
+
static createWriter(agent: AgentName): AgentWriter;
|
|
8
8
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -2141,7 +2141,7 @@ var AGENT_MAPPINGS = {
|
|
|
2141
2141
|
mcpPath: ".mcp.json"
|
|
2142
2142
|
},
|
|
2143
2143
|
cursor: {
|
|
2144
|
-
path: ".cursor/rules/{name}.
|
|
2144
|
+
path: ".cursor/rules/{name}.mdc",
|
|
2145
2145
|
format: "frontmatter",
|
|
2146
2146
|
directory: ".cursor/rules",
|
|
2147
2147
|
mcpPath: "~/.cursor/mcp.json"
|
|
@@ -2156,6 +2156,11 @@ var AGENT_MAPPINGS = {
|
|
|
2156
2156
|
format: "markdown",
|
|
2157
2157
|
directory: ".roo/rules",
|
|
2158
2158
|
mcpPath: ".roo/mcp.json"
|
|
2159
|
+
},
|
|
2160
|
+
generic: {
|
|
2161
|
+
path: "{name}.md",
|
|
2162
|
+
format: "markdown",
|
|
2163
|
+
mcpPath: "mcp.json"
|
|
2159
2164
|
}
|
|
2160
2165
|
};
|
|
2161
2166
|
function getAgentPath(agent, name = "global") {
|
|
@@ -2210,11 +2215,12 @@ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
|
2210
2215
|
class CursorWriter {
|
|
2211
2216
|
formatContent(content, rule) {
|
|
2212
2217
|
const ruleName = this.extractRuleName(rule.file);
|
|
2218
|
+
const hasGlobs = rule.globs && rule.globs.length > 0;
|
|
2213
2219
|
const frontmatter = [
|
|
2214
2220
|
"---",
|
|
2215
2221
|
`description: AI Rules - ${ruleName}`,
|
|
2216
|
-
`globs: ${rule.globs
|
|
2217
|
-
"alwaysApply: true",
|
|
2222
|
+
`globs: ${hasGlobs ? rule.globs : "**/*"}`,
|
|
2223
|
+
"alwaysApply: " + (hasGlobs ? "false" : "true"),
|
|
2218
2224
|
"---",
|
|
2219
2225
|
""
|
|
2220
2226
|
].join(`
|
|
@@ -2251,6 +2257,7 @@ class AgentWriterFactory {
|
|
|
2251
2257
|
case "claude":
|
|
2252
2258
|
case "codex":
|
|
2253
2259
|
case "roocode":
|
|
2260
|
+
case "generic":
|
|
2254
2261
|
return new MarkdownWriter;
|
|
2255
2262
|
default:
|
|
2256
2263
|
return new MarkdownWriter;
|
|
@@ -2334,25 +2341,32 @@ class AgentDistributor {
|
|
|
2334
2341
|
await this.distributeToAgent(agent, rule, content);
|
|
2335
2342
|
}
|
|
2336
2343
|
}
|
|
2344
|
+
getAgentName(agent) {
|
|
2345
|
+
return typeof agent === "string" ? agent : agent.name;
|
|
2346
|
+
}
|
|
2347
|
+
getCustomPath(agent) {
|
|
2348
|
+
return typeof agent === "object" ? agent.to : undefined;
|
|
2349
|
+
}
|
|
2337
2350
|
async distributeToAgent(agent, rule, content) {
|
|
2338
|
-
const
|
|
2339
|
-
const
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
const fullDir = join2(rule.to, agentDir);
|
|
2344
|
-
mkdirSync(fullDir, { recursive: true });
|
|
2351
|
+
const agentName = this.getAgentName(agent);
|
|
2352
|
+
const customPath = this.getCustomPath(agent);
|
|
2353
|
+
let targetPath;
|
|
2354
|
+
if (customPath) {
|
|
2355
|
+
targetPath = customPath;
|
|
2345
2356
|
} else {
|
|
2346
|
-
|
|
2357
|
+
const ruleName = this.extractRuleName(rule.file);
|
|
2358
|
+
const agentPath = getAgentPath(agentName, ruleName);
|
|
2359
|
+
targetPath = join2(rule.to, agentPath);
|
|
2347
2360
|
}
|
|
2348
|
-
|
|
2361
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
2362
|
+
const writer = AgentWriterFactory.createWriter(agentName);
|
|
2349
2363
|
const formattedContent = writer.formatContent(content, rule);
|
|
2350
2364
|
const context = {
|
|
2351
2365
|
config: this.config,
|
|
2352
2366
|
rule,
|
|
2353
2367
|
content: formattedContent,
|
|
2354
2368
|
targetPath,
|
|
2355
|
-
agent
|
|
2369
|
+
agent: agentName
|
|
2356
2370
|
};
|
|
2357
2371
|
const finalContent = await this.applyHooks(context);
|
|
2358
2372
|
writeFileSync(targetPath, finalContent, "utf-8");
|
|
@@ -2509,6 +2523,12 @@ class GitIgnoreManager {
|
|
|
2509
2523
|
constructor(config) {
|
|
2510
2524
|
this.config = config;
|
|
2511
2525
|
}
|
|
2526
|
+
getAgentName(agent) {
|
|
2527
|
+
return typeof agent === "string" ? agent : agent.name;
|
|
2528
|
+
}
|
|
2529
|
+
getCustomPath(agent) {
|
|
2530
|
+
return typeof agent === "object" ? agent.to : undefined;
|
|
2531
|
+
}
|
|
2512
2532
|
async updateGitIgnore() {
|
|
2513
2533
|
const paths = this.collectGeneratedPaths();
|
|
2514
2534
|
if (paths.length === 0) {
|
|
@@ -2539,22 +2559,34 @@ class GitIgnoreManager {
|
|
|
2539
2559
|
const paths = new Set;
|
|
2540
2560
|
for (const rule of this.config.rules) {
|
|
2541
2561
|
for (const agent of rule.targets) {
|
|
2542
|
-
const
|
|
2543
|
-
const
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
const
|
|
2549
|
-
|
|
2562
|
+
const agentName = this.getAgentName(agent);
|
|
2563
|
+
const customPath = this.getCustomPath(agent);
|
|
2564
|
+
if (customPath) {
|
|
2565
|
+
paths.add(customPath);
|
|
2566
|
+
} else {
|
|
2567
|
+
const ruleName = this.extractRuleName(rule.file);
|
|
2568
|
+
const agentPath = getAgentPath(agentName, ruleName);
|
|
2569
|
+
const fullPath = `${rule.to}/${agentPath}`.replace(/\/+/g, "/");
|
|
2570
|
+
paths.add(fullPath);
|
|
2571
|
+
const agentDir = getAgentDirectory(agentName);
|
|
2572
|
+
if (agentDir) {
|
|
2573
|
+
const fullDir = `${rule.to}/${agentDir}`.replace(/\/+/g, "/");
|
|
2574
|
+
paths.add(`${fullDir}/`);
|
|
2575
|
+
}
|
|
2550
2576
|
}
|
|
2551
2577
|
}
|
|
2552
2578
|
}
|
|
2553
2579
|
if (this.config.commands) {
|
|
2554
2580
|
for (const command of this.config.commands) {
|
|
2555
2581
|
for (const agent of command.targets) {
|
|
2556
|
-
const
|
|
2557
|
-
|
|
2582
|
+
const agentName = this.getAgentName(agent);
|
|
2583
|
+
const customPath = this.getCustomPath(agent);
|
|
2584
|
+
if (customPath) {
|
|
2585
|
+
paths.add(customPath);
|
|
2586
|
+
} else {
|
|
2587
|
+
const agentPath = getAgentPath(agentName, command.command);
|
|
2588
|
+
paths.add(agentPath);
|
|
2589
|
+
}
|
|
2558
2590
|
}
|
|
2559
2591
|
}
|
|
2560
2592
|
}
|
|
@@ -2754,24 +2786,42 @@ class AIRulesCore {
|
|
|
2754
2786
|
throw new Error(`Duplicate MCP names found: ${duplicates.join(", ")}`);
|
|
2755
2787
|
}
|
|
2756
2788
|
}
|
|
2789
|
+
getAgentName(agent) {
|
|
2790
|
+
return typeof agent === "string" ? agent : agent.name;
|
|
2791
|
+
}
|
|
2792
|
+
getCustomPath(agent) {
|
|
2793
|
+
return typeof agent === "object" ? agent.to : undefined;
|
|
2794
|
+
}
|
|
2757
2795
|
collectAllGeneratedPaths() {
|
|
2758
2796
|
const paths = [];
|
|
2759
2797
|
for (const rule of this.config.rules) {
|
|
2760
2798
|
for (const agent of rule.targets) {
|
|
2761
|
-
const
|
|
2762
|
-
const
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2799
|
+
const agentName = this.getAgentName(agent);
|
|
2800
|
+
const customPath = this.getCustomPath(agent);
|
|
2801
|
+
if (customPath) {
|
|
2802
|
+
paths.push(customPath);
|
|
2803
|
+
} else {
|
|
2804
|
+
const ruleName = rule.file.split("/").pop()?.replace(".md", "") || "rule";
|
|
2805
|
+
const agentPath = getAgentPath(agentName, ruleName);
|
|
2806
|
+
let fullPath = `${rule.to}/${agentPath}`.replace(/\/+/g, "/");
|
|
2807
|
+
if (fullPath.startsWith("./")) {
|
|
2808
|
+
fullPath = fullPath.substring(2);
|
|
2809
|
+
}
|
|
2810
|
+
paths.push(fullPath);
|
|
2766
2811
|
}
|
|
2767
|
-
paths.push(fullPath);
|
|
2768
2812
|
}
|
|
2769
2813
|
}
|
|
2770
2814
|
if (this.config.commands) {
|
|
2771
2815
|
for (const command of this.config.commands) {
|
|
2772
2816
|
for (const agent of command.targets) {
|
|
2773
|
-
const
|
|
2774
|
-
|
|
2817
|
+
const agentName = this.getAgentName(agent);
|
|
2818
|
+
const customPath = this.getCustomPath(agent);
|
|
2819
|
+
if (customPath) {
|
|
2820
|
+
paths.push(customPath);
|
|
2821
|
+
} else {
|
|
2822
|
+
const agentPath = getAgentPath(agentName, command.command);
|
|
2823
|
+
paths.push(agentPath);
|
|
2824
|
+
}
|
|
2775
2825
|
}
|
|
2776
2826
|
}
|
|
2777
2827
|
}
|
|
@@ -2876,9 +2926,18 @@ class ConfigLoader {
|
|
|
2876
2926
|
if (!Array.isArray(r.targets) || r.targets.length === 0) {
|
|
2877
2927
|
throw new Error(`Rule at index ${index}: Rule.targets must be a non-empty array`);
|
|
2878
2928
|
}
|
|
2879
|
-
const
|
|
2880
|
-
if (!r.targets.every((agent) =>
|
|
2881
|
-
|
|
2929
|
+
const validAgentNames = ["claude", "cursor", "codex", "roocode", "generic"];
|
|
2930
|
+
if (!r.targets.every((agent) => {
|
|
2931
|
+
if (typeof agent === "string") {
|
|
2932
|
+
return validAgentNames.includes(agent);
|
|
2933
|
+
}
|
|
2934
|
+
if (typeof agent === "object" && agent !== null) {
|
|
2935
|
+
const a = agent;
|
|
2936
|
+
return validAgentNames.includes(a.name) && (a.to === undefined || typeof a.to === "string");
|
|
2937
|
+
}
|
|
2938
|
+
return false;
|
|
2939
|
+
})) {
|
|
2940
|
+
throw new Error(`Rule at index ${index}: Rule.targets must contain valid agents: ${validAgentNames.join(", ")}, or objects with {name, to?}`);
|
|
2882
2941
|
}
|
|
2883
2942
|
}
|
|
2884
2943
|
static createInitialConfig() {
|
|
@@ -2887,127 +2946,30 @@ class ConfigLoader {
|
|
|
2887
2946
|
static createTypedConfig() {
|
|
2888
2947
|
return `import { defineRules } from 'glooit';
|
|
2889
2948
|
|
|
2890
|
-
// defineRules() provides TypeScript IntelliSense and validation
|
|
2891
2949
|
export default defineRules({
|
|
2892
|
-
// Directory where glooit stores configuration files
|
|
2893
2950
|
configDir: '.glooit',
|
|
2894
|
-
|
|
2895
|
-
// Default targets for all rules (can be overridden per rule)
|
|
2896
|
-
targets: ['claude', 'cursor'],
|
|
2897
|
-
|
|
2898
|
-
// Rules define how to sync your files to different AI agents
|
|
2899
2951
|
rules: [
|
|
2900
2952
|
{
|
|
2901
2953
|
name: 'main',
|
|
2902
|
-
file: '.glooit/main.md',
|
|
2903
|
-
to: './',
|
|
2904
|
-
targets: ['claude', 'cursor']
|
|
2905
|
-
}
|
|
2906
|
-
// Add more rules here:
|
|
2907
|
-
// {
|
|
2908
|
-
// name: 'coding-standards',
|
|
2909
|
-
// file: '.glooit/coding-rules.md',
|
|
2910
|
-
// to: './',
|
|
2911
|
-
// targets: ['claude'],
|
|
2912
|
-
// globs: '**/*.{ts,js,tsx,jsx}' // Optional: only apply to certain file patterns
|
|
2913
|
-
// }
|
|
2914
|
-
],
|
|
2915
|
-
|
|
2916
|
-
// MCP (Model Context Protocol) server configurations
|
|
2917
|
-
mcps: [
|
|
2918
|
-
// Example MCP server configurations:
|
|
2919
|
-
// {
|
|
2920
|
-
// name: 'database',
|
|
2921
|
-
// config: {
|
|
2922
|
-
// command: 'npx',
|
|
2923
|
-
// args: ['@modelcontextprotocol/server-postgres'],
|
|
2924
|
-
// env: { DATABASE_URL: process.env.DATABASE_URL }
|
|
2925
|
-
// },
|
|
2926
|
-
// targets: ['claude']
|
|
2927
|
-
// },
|
|
2928
|
-
// {
|
|
2929
|
-
// name: 'filesystem',
|
|
2930
|
-
// config: {
|
|
2931
|
-
// command: 'npx',
|
|
2932
|
-
// args: ['@modelcontextprotocol/server-filesystem', process.cwd()]
|
|
2933
|
-
// },
|
|
2934
|
-
// targets: ['claude', 'cursor']
|
|
2935
|
-
// }
|
|
2954
|
+
file: '.glooit/main.md',
|
|
2955
|
+
to: './',
|
|
2956
|
+
targets: ['claude', 'cursor']
|
|
2957
|
+
}
|
|
2936
2958
|
],
|
|
2937
|
-
|
|
2938
|
-
// Additional options:
|
|
2939
|
-
// mergeMcps: true, // Merge with existing MCP configs (default: true)
|
|
2940
|
-
// backup: { // Backup settings
|
|
2941
|
-
// enabled: true, // Create backups before syncing (default: true)
|
|
2942
|
-
// retention: 10 // Keep last 10 backups (default: 10)
|
|
2943
|
-
// },
|
|
2944
|
-
// hooks: { // Custom hooks for advanced workflows
|
|
2945
|
-
// before: [], // Run before sync
|
|
2946
|
-
// after: [], // Run after sync
|
|
2947
|
-
// error: [] // Run on error
|
|
2948
|
-
// }
|
|
2949
2959
|
});
|
|
2950
2960
|
`;
|
|
2951
2961
|
}
|
|
2952
2962
|
static createPlainConfig() {
|
|
2953
2963
|
return `export default {
|
|
2954
|
-
// Directory where glooit stores configuration files
|
|
2955
2964
|
configDir: '.glooit',
|
|
2956
|
-
|
|
2957
|
-
// Default targets for all rules (can be overridden per rule)
|
|
2958
|
-
targets: ['claude', 'cursor'],
|
|
2959
|
-
|
|
2960
|
-
// Rules define how to sync your files to different AI agents
|
|
2961
2965
|
rules: [
|
|
2962
2966
|
{
|
|
2963
2967
|
name: 'main',
|
|
2964
|
-
file: '.glooit/main.md',
|
|
2965
|
-
to: './',
|
|
2966
|
-
targets: ['claude', 'cursor']
|
|
2967
|
-
}
|
|
2968
|
-
// Add more rules here:
|
|
2969
|
-
// {
|
|
2970
|
-
// name: 'coding-standards',
|
|
2971
|
-
// file: '.glooit/coding-rules.md',
|
|
2972
|
-
// to: './',
|
|
2973
|
-
// targets: ['claude'],
|
|
2974
|
-
// globs: '**/*.{ts,js,tsx,jsx}' // Optional: only apply to certain file patterns
|
|
2975
|
-
// }
|
|
2968
|
+
file: '.glooit/main.md',
|
|
2969
|
+
to: './',
|
|
2970
|
+
targets: ['claude', 'cursor']
|
|
2971
|
+
}
|
|
2976
2972
|
],
|
|
2977
|
-
|
|
2978
|
-
// MCP (Model Context Protocol) server configurations
|
|
2979
|
-
mcps: [
|
|
2980
|
-
// Example MCP server configurations:
|
|
2981
|
-
// {
|
|
2982
|
-
// name: 'database',
|
|
2983
|
-
// config: {
|
|
2984
|
-
// command: 'npx',
|
|
2985
|
-
// args: ['@modelcontextprotocol/server-postgres'],
|
|
2986
|
-
// env: { DATABASE_URL: process.env.DATABASE_URL }
|
|
2987
|
-
// },
|
|
2988
|
-
// targets: ['claude']
|
|
2989
|
-
// },
|
|
2990
|
-
// {
|
|
2991
|
-
// name: 'filesystem',
|
|
2992
|
-
// config: {
|
|
2993
|
-
// command: 'npx',
|
|
2994
|
-
// args: ['@modelcontextprotocol/server-filesystem', process.cwd()]
|
|
2995
|
-
// },
|
|
2996
|
-
// targets: ['claude', 'cursor']
|
|
2997
|
-
// }
|
|
2998
|
-
]
|
|
2999
|
-
|
|
3000
|
-
// Additional options:
|
|
3001
|
-
// mergeMcps: true, // Merge with existing MCP configs (default: true)
|
|
3002
|
-
// backup: { // Backup settings
|
|
3003
|
-
// enabled: true, // Create backups before syncing (default: true)
|
|
3004
|
-
// retention: 10 // Keep last 10 backups (default: 10)
|
|
3005
|
-
// },
|
|
3006
|
-
// hooks: { // Custom hooks for advanced workflows
|
|
3007
|
-
// before: [], // Run before sync
|
|
3008
|
-
// after: [], // Run after sync
|
|
3009
|
-
// error: [] // Run on error
|
|
3010
|
-
// }
|
|
3011
2973
|
};
|
|
3012
2974
|
`;
|
|
3013
2975
|
}
|
|
@@ -3373,7 +3335,7 @@ function constructCommand(value, args) {
|
|
|
3373
3335
|
import { execSync } from "child_process";
|
|
3374
3336
|
import { createInterface } from "readline";
|
|
3375
3337
|
// package.json
|
|
3376
|
-
var version = "0.5.
|
|
3338
|
+
var version = "0.5.3";
|
|
3377
3339
|
|
|
3378
3340
|
// src/cli/index.ts
|
|
3379
3341
|
var args = process.argv.slice(2);
|
package/dist/core/gitignore.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export declare class GitIgnoreManager {
|
|
|
4
4
|
private gitignorePath;
|
|
5
5
|
private marker;
|
|
6
6
|
constructor(config: Config);
|
|
7
|
+
private getAgentName;
|
|
8
|
+
private getCustomPath;
|
|
7
9
|
updateGitIgnore(): Promise<void>;
|
|
8
10
|
cleanupGitIgnore(): Promise<void>;
|
|
9
11
|
private collectGeneratedPaths;
|
package/dist/core/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -10,8 +10,18 @@ var __export = (target, all) => {
|
|
|
10
10
|
};
|
|
11
11
|
|
|
12
12
|
// src/types/index.ts
|
|
13
|
+
function isValidAgentName(agentName) {
|
|
14
|
+
return ["claude", "cursor", "codex", "roocode", "generic"].includes(agentName);
|
|
15
|
+
}
|
|
13
16
|
function isValidAgent(agent) {
|
|
14
|
-
|
|
17
|
+
if (typeof agent === "string") {
|
|
18
|
+
return isValidAgentName(agent);
|
|
19
|
+
}
|
|
20
|
+
if (typeof agent === "object" && agent !== null) {
|
|
21
|
+
const a = agent;
|
|
22
|
+
return isValidAgentName(a.name) && (a.to === undefined || typeof a.to === "string");
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
15
25
|
}
|
|
16
26
|
function validateRule(rule) {
|
|
17
27
|
if (!rule || typeof rule !== "object") {
|
|
@@ -28,7 +38,7 @@ function validateRule(rule) {
|
|
|
28
38
|
throw new Error("Rule.targets must be a non-empty array");
|
|
29
39
|
}
|
|
30
40
|
if (!r.targets.every(isValidAgent)) {
|
|
31
|
-
throw new Error("Rule.targets must contain valid agents: claude, cursor, codex, roocode");
|
|
41
|
+
throw new Error("Rule.targets must contain valid agents: claude, cursor, codex, roocode, generic, or objects with {name, to?}");
|
|
32
42
|
}
|
|
33
43
|
}
|
|
34
44
|
function validateConfig(config) {
|
|
@@ -79,7 +89,7 @@ var AGENT_MAPPINGS = {
|
|
|
79
89
|
mcpPath: ".mcp.json"
|
|
80
90
|
},
|
|
81
91
|
cursor: {
|
|
82
|
-
path: ".cursor/rules/{name}.
|
|
92
|
+
path: ".cursor/rules/{name}.mdc",
|
|
83
93
|
format: "frontmatter",
|
|
84
94
|
directory: ".cursor/rules",
|
|
85
95
|
mcpPath: "~/.cursor/mcp.json"
|
|
@@ -94,6 +104,11 @@ var AGENT_MAPPINGS = {
|
|
|
94
104
|
format: "markdown",
|
|
95
105
|
directory: ".roo/rules",
|
|
96
106
|
mcpPath: ".roo/mcp.json"
|
|
107
|
+
},
|
|
108
|
+
generic: {
|
|
109
|
+
path: "{name}.md",
|
|
110
|
+
format: "markdown",
|
|
111
|
+
mcpPath: "mcp.json"
|
|
97
112
|
}
|
|
98
113
|
};
|
|
99
114
|
function getAgentPath(agent, name = "global") {
|
|
@@ -148,11 +163,12 @@ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
|
148
163
|
class CursorWriter {
|
|
149
164
|
formatContent(content, rule) {
|
|
150
165
|
const ruleName = this.extractRuleName(rule.file);
|
|
166
|
+
const hasGlobs = rule.globs && rule.globs.length > 0;
|
|
151
167
|
const frontmatter = [
|
|
152
168
|
"---",
|
|
153
169
|
`description: AI Rules - ${ruleName}`,
|
|
154
|
-
`globs: ${rule.globs
|
|
155
|
-
"alwaysApply: true",
|
|
170
|
+
`globs: ${hasGlobs ? rule.globs : "**/*"}`,
|
|
171
|
+
"alwaysApply: " + (hasGlobs ? "false" : "true"),
|
|
156
172
|
"---",
|
|
157
173
|
""
|
|
158
174
|
].join(`
|
|
@@ -189,6 +205,7 @@ class AgentWriterFactory {
|
|
|
189
205
|
case "claude":
|
|
190
206
|
case "codex":
|
|
191
207
|
case "roocode":
|
|
208
|
+
case "generic":
|
|
192
209
|
return new MarkdownWriter;
|
|
193
210
|
default:
|
|
194
211
|
return new MarkdownWriter;
|
|
@@ -272,25 +289,32 @@ class AgentDistributor {
|
|
|
272
289
|
await this.distributeToAgent(agent, rule, content);
|
|
273
290
|
}
|
|
274
291
|
}
|
|
292
|
+
getAgentName(agent) {
|
|
293
|
+
return typeof agent === "string" ? agent : agent.name;
|
|
294
|
+
}
|
|
295
|
+
getCustomPath(agent) {
|
|
296
|
+
return typeof agent === "object" ? agent.to : undefined;
|
|
297
|
+
}
|
|
275
298
|
async distributeToAgent(agent, rule, content) {
|
|
276
|
-
const
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const fullDir = join2(rule.to, agentDir);
|
|
282
|
-
mkdirSync(fullDir, { recursive: true });
|
|
299
|
+
const agentName = this.getAgentName(agent);
|
|
300
|
+
const customPath = this.getCustomPath(agent);
|
|
301
|
+
let targetPath;
|
|
302
|
+
if (customPath) {
|
|
303
|
+
targetPath = customPath;
|
|
283
304
|
} else {
|
|
284
|
-
|
|
305
|
+
const ruleName = this.extractRuleName(rule.file);
|
|
306
|
+
const agentPath = getAgentPath(agentName, ruleName);
|
|
307
|
+
targetPath = join2(rule.to, agentPath);
|
|
285
308
|
}
|
|
286
|
-
|
|
309
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
310
|
+
const writer = AgentWriterFactory.createWriter(agentName);
|
|
287
311
|
const formattedContent = writer.formatContent(content, rule);
|
|
288
312
|
const context = {
|
|
289
313
|
config: this.config,
|
|
290
314
|
rule,
|
|
291
315
|
content: formattedContent,
|
|
292
316
|
targetPath,
|
|
293
|
-
agent
|
|
317
|
+
agent: agentName
|
|
294
318
|
};
|
|
295
319
|
const finalContent = await this.applyHooks(context);
|
|
296
320
|
writeFileSync(targetPath, finalContent, "utf-8");
|
|
@@ -447,6 +471,12 @@ class GitIgnoreManager {
|
|
|
447
471
|
constructor(config) {
|
|
448
472
|
this.config = config;
|
|
449
473
|
}
|
|
474
|
+
getAgentName(agent) {
|
|
475
|
+
return typeof agent === "string" ? agent : agent.name;
|
|
476
|
+
}
|
|
477
|
+
getCustomPath(agent) {
|
|
478
|
+
return typeof agent === "object" ? agent.to : undefined;
|
|
479
|
+
}
|
|
450
480
|
async updateGitIgnore() {
|
|
451
481
|
const paths = this.collectGeneratedPaths();
|
|
452
482
|
if (paths.length === 0) {
|
|
@@ -477,22 +507,34 @@ class GitIgnoreManager {
|
|
|
477
507
|
const paths = new Set;
|
|
478
508
|
for (const rule of this.config.rules) {
|
|
479
509
|
for (const agent of rule.targets) {
|
|
480
|
-
const
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
const
|
|
487
|
-
|
|
510
|
+
const agentName = this.getAgentName(agent);
|
|
511
|
+
const customPath = this.getCustomPath(agent);
|
|
512
|
+
if (customPath) {
|
|
513
|
+
paths.add(customPath);
|
|
514
|
+
} else {
|
|
515
|
+
const ruleName = this.extractRuleName(rule.file);
|
|
516
|
+
const agentPath = getAgentPath(agentName, ruleName);
|
|
517
|
+
const fullPath = `${rule.to}/${agentPath}`.replace(/\/+/g, "/");
|
|
518
|
+
paths.add(fullPath);
|
|
519
|
+
const agentDir = getAgentDirectory(agentName);
|
|
520
|
+
if (agentDir) {
|
|
521
|
+
const fullDir = `${rule.to}/${agentDir}`.replace(/\/+/g, "/");
|
|
522
|
+
paths.add(`${fullDir}/`);
|
|
523
|
+
}
|
|
488
524
|
}
|
|
489
525
|
}
|
|
490
526
|
}
|
|
491
527
|
if (this.config.commands) {
|
|
492
528
|
for (const command of this.config.commands) {
|
|
493
529
|
for (const agent of command.targets) {
|
|
494
|
-
const
|
|
495
|
-
|
|
530
|
+
const agentName = this.getAgentName(agent);
|
|
531
|
+
const customPath = this.getCustomPath(agent);
|
|
532
|
+
if (customPath) {
|
|
533
|
+
paths.add(customPath);
|
|
534
|
+
} else {
|
|
535
|
+
const agentPath = getAgentPath(agentName, command.command);
|
|
536
|
+
paths.add(agentPath);
|
|
537
|
+
}
|
|
496
538
|
}
|
|
497
539
|
}
|
|
498
540
|
}
|
|
@@ -692,24 +734,42 @@ class AIRulesCore {
|
|
|
692
734
|
throw new Error(`Duplicate MCP names found: ${duplicates.join(", ")}`);
|
|
693
735
|
}
|
|
694
736
|
}
|
|
737
|
+
getAgentName(agent) {
|
|
738
|
+
return typeof agent === "string" ? agent : agent.name;
|
|
739
|
+
}
|
|
740
|
+
getCustomPath(agent) {
|
|
741
|
+
return typeof agent === "object" ? agent.to : undefined;
|
|
742
|
+
}
|
|
695
743
|
collectAllGeneratedPaths() {
|
|
696
744
|
const paths = [];
|
|
697
745
|
for (const rule of this.config.rules) {
|
|
698
746
|
for (const agent of rule.targets) {
|
|
699
|
-
const
|
|
700
|
-
const
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
747
|
+
const agentName = this.getAgentName(agent);
|
|
748
|
+
const customPath = this.getCustomPath(agent);
|
|
749
|
+
if (customPath) {
|
|
750
|
+
paths.push(customPath);
|
|
751
|
+
} else {
|
|
752
|
+
const ruleName = rule.file.split("/").pop()?.replace(".md", "") || "rule";
|
|
753
|
+
const agentPath = getAgentPath(agentName, ruleName);
|
|
754
|
+
let fullPath = `${rule.to}/${agentPath}`.replace(/\/+/g, "/");
|
|
755
|
+
if (fullPath.startsWith("./")) {
|
|
756
|
+
fullPath = fullPath.substring(2);
|
|
757
|
+
}
|
|
758
|
+
paths.push(fullPath);
|
|
704
759
|
}
|
|
705
|
-
paths.push(fullPath);
|
|
706
760
|
}
|
|
707
761
|
}
|
|
708
762
|
if (this.config.commands) {
|
|
709
763
|
for (const command of this.config.commands) {
|
|
710
764
|
for (const agent of command.targets) {
|
|
711
|
-
const
|
|
712
|
-
|
|
765
|
+
const agentName = this.getAgentName(agent);
|
|
766
|
+
const customPath = this.getCustomPath(agent);
|
|
767
|
+
if (customPath) {
|
|
768
|
+
paths.push(customPath);
|
|
769
|
+
} else {
|
|
770
|
+
const agentPath = getAgentPath(agentName, command.command);
|
|
771
|
+
paths.push(agentPath);
|
|
772
|
+
}
|
|
713
773
|
}
|
|
714
774
|
}
|
|
715
775
|
}
|
|
@@ -813,9 +873,18 @@ class ConfigLoader {
|
|
|
813
873
|
if (!Array.isArray(r.targets) || r.targets.length === 0) {
|
|
814
874
|
throw new Error(`Rule at index ${index}: Rule.targets must be a non-empty array`);
|
|
815
875
|
}
|
|
816
|
-
const
|
|
817
|
-
if (!r.targets.every((agent) =>
|
|
818
|
-
|
|
876
|
+
const validAgentNames = ["claude", "cursor", "codex", "roocode", "generic"];
|
|
877
|
+
if (!r.targets.every((agent) => {
|
|
878
|
+
if (typeof agent === "string") {
|
|
879
|
+
return validAgentNames.includes(agent);
|
|
880
|
+
}
|
|
881
|
+
if (typeof agent === "object" && agent !== null) {
|
|
882
|
+
const a = agent;
|
|
883
|
+
return validAgentNames.includes(a.name) && (a.to === undefined || typeof a.to === "string");
|
|
884
|
+
}
|
|
885
|
+
return false;
|
|
886
|
+
})) {
|
|
887
|
+
throw new Error(`Rule at index ${index}: Rule.targets must contain valid agents: ${validAgentNames.join(", ")}, or objects with {name, to?}`);
|
|
819
888
|
}
|
|
820
889
|
}
|
|
821
890
|
static createInitialConfig() {
|
|
@@ -824,127 +893,30 @@ class ConfigLoader {
|
|
|
824
893
|
static createTypedConfig() {
|
|
825
894
|
return `import { defineRules } from 'glooit';
|
|
826
895
|
|
|
827
|
-
// defineRules() provides TypeScript IntelliSense and validation
|
|
828
896
|
export default defineRules({
|
|
829
|
-
// Directory where glooit stores configuration files
|
|
830
897
|
configDir: '.glooit',
|
|
831
|
-
|
|
832
|
-
// Default targets for all rules (can be overridden per rule)
|
|
833
|
-
targets: ['claude', 'cursor'],
|
|
834
|
-
|
|
835
|
-
// Rules define how to sync your files to different AI agents
|
|
836
898
|
rules: [
|
|
837
899
|
{
|
|
838
900
|
name: 'main',
|
|
839
|
-
file: '.glooit/main.md',
|
|
840
|
-
to: './',
|
|
841
|
-
targets: ['claude', 'cursor']
|
|
901
|
+
file: '.glooit/main.md',
|
|
902
|
+
to: './',
|
|
903
|
+
targets: ['claude', 'cursor']
|
|
842
904
|
}
|
|
843
|
-
// Add more rules here:
|
|
844
|
-
// {
|
|
845
|
-
// name: 'coding-standards',
|
|
846
|
-
// file: '.glooit/coding-rules.md',
|
|
847
|
-
// to: './',
|
|
848
|
-
// targets: ['claude'],
|
|
849
|
-
// globs: '**/*.{ts,js,tsx,jsx}' // Optional: only apply to certain file patterns
|
|
850
|
-
// }
|
|
851
905
|
],
|
|
852
|
-
|
|
853
|
-
// MCP (Model Context Protocol) server configurations
|
|
854
|
-
mcps: [
|
|
855
|
-
// Example MCP server configurations:
|
|
856
|
-
// {
|
|
857
|
-
// name: 'database',
|
|
858
|
-
// config: {
|
|
859
|
-
// command: 'npx',
|
|
860
|
-
// args: ['@modelcontextprotocol/server-postgres'],
|
|
861
|
-
// env: { DATABASE_URL: process.env.DATABASE_URL }
|
|
862
|
-
// },
|
|
863
|
-
// targets: ['claude']
|
|
864
|
-
// },
|
|
865
|
-
// {
|
|
866
|
-
// name: 'filesystem',
|
|
867
|
-
// config: {
|
|
868
|
-
// command: 'npx',
|
|
869
|
-
// args: ['@modelcontextprotocol/server-filesystem', process.cwd()]
|
|
870
|
-
// },
|
|
871
|
-
// targets: ['claude', 'cursor']
|
|
872
|
-
// }
|
|
873
|
-
],
|
|
874
|
-
|
|
875
|
-
// Additional options:
|
|
876
|
-
// mergeMcps: true, // Merge with existing MCP configs (default: true)
|
|
877
|
-
// backup: { // Backup settings
|
|
878
|
-
// enabled: true, // Create backups before syncing (default: true)
|
|
879
|
-
// retention: 10 // Keep last 10 backups (default: 10)
|
|
880
|
-
// },
|
|
881
|
-
// hooks: { // Custom hooks for advanced workflows
|
|
882
|
-
// before: [], // Run before sync
|
|
883
|
-
// after: [], // Run after sync
|
|
884
|
-
// error: [] // Run on error
|
|
885
|
-
// }
|
|
886
906
|
});
|
|
887
907
|
`;
|
|
888
908
|
}
|
|
889
909
|
static createPlainConfig() {
|
|
890
910
|
return `export default {
|
|
891
|
-
// Directory where glooit stores configuration files
|
|
892
911
|
configDir: '.glooit',
|
|
893
|
-
|
|
894
|
-
// Default targets for all rules (can be overridden per rule)
|
|
895
|
-
targets: ['claude', 'cursor'],
|
|
896
|
-
|
|
897
|
-
// Rules define how to sync your files to different AI agents
|
|
898
912
|
rules: [
|
|
899
913
|
{
|
|
900
914
|
name: 'main',
|
|
901
|
-
file: '.glooit/main.md',
|
|
902
|
-
to: './',
|
|
903
|
-
targets: ['claude', 'cursor']
|
|
915
|
+
file: '.glooit/main.md',
|
|
916
|
+
to: './',
|
|
917
|
+
targets: ['claude', 'cursor']
|
|
904
918
|
}
|
|
905
|
-
// Add more rules here:
|
|
906
|
-
// {
|
|
907
|
-
// name: 'coding-standards',
|
|
908
|
-
// file: '.glooit/coding-rules.md',
|
|
909
|
-
// to: './',
|
|
910
|
-
// targets: ['claude'],
|
|
911
|
-
// globs: '**/*.{ts,js,tsx,jsx}' // Optional: only apply to certain file patterns
|
|
912
|
-
// }
|
|
913
919
|
],
|
|
914
|
-
|
|
915
|
-
// MCP (Model Context Protocol) server configurations
|
|
916
|
-
mcps: [
|
|
917
|
-
// Example MCP server configurations:
|
|
918
|
-
// {
|
|
919
|
-
// name: 'database',
|
|
920
|
-
// config: {
|
|
921
|
-
// command: 'npx',
|
|
922
|
-
// args: ['@modelcontextprotocol/server-postgres'],
|
|
923
|
-
// env: { DATABASE_URL: process.env.DATABASE_URL }
|
|
924
|
-
// },
|
|
925
|
-
// targets: ['claude']
|
|
926
|
-
// },
|
|
927
|
-
// {
|
|
928
|
-
// name: 'filesystem',
|
|
929
|
-
// config: {
|
|
930
|
-
// command: 'npx',
|
|
931
|
-
// args: ['@modelcontextprotocol/server-filesystem', process.cwd()]
|
|
932
|
-
// },
|
|
933
|
-
// targets: ['claude', 'cursor']
|
|
934
|
-
// }
|
|
935
|
-
]
|
|
936
|
-
|
|
937
|
-
// Additional options:
|
|
938
|
-
// mergeMcps: true, // Merge with existing MCP configs (default: true)
|
|
939
|
-
// backup: { // Backup settings
|
|
940
|
-
// enabled: true, // Create backups before syncing (default: true)
|
|
941
|
-
// retention: 10 // Keep last 10 backups (default: 10)
|
|
942
|
-
// },
|
|
943
|
-
// hooks: { // Custom hooks for advanced workflows
|
|
944
|
-
// before: [], // Run before sync
|
|
945
|
-
// after: [], // Run after sync
|
|
946
|
-
// error: [] // Run on error
|
|
947
|
-
// }
|
|
948
920
|
};
|
|
949
921
|
`;
|
|
950
922
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type AgentName = 'claude' | 'cursor' | 'codex' | 'roocode' | 'generic';
|
|
2
|
+
export interface AgentTarget {
|
|
3
|
+
name: AgentName;
|
|
4
|
+
to?: string;
|
|
5
|
+
}
|
|
6
|
+
export type Agent = AgentName | AgentTarget;
|
|
2
7
|
export interface Rule {
|
|
3
8
|
name?: string;
|
|
4
9
|
file: string;
|
|
@@ -25,7 +30,7 @@ export interface McpConfig {
|
|
|
25
30
|
export interface Mcp {
|
|
26
31
|
name: string;
|
|
27
32
|
config: McpConfig;
|
|
28
|
-
targets?:
|
|
33
|
+
targets?: AgentName[];
|
|
29
34
|
outputPath?: string;
|
|
30
35
|
}
|
|
31
36
|
export interface ResolvedMcp extends Omit<Mcp, 'outputPath'> {
|
|
@@ -63,7 +68,7 @@ export interface SyncContext {
|
|
|
63
68
|
rule: Rule;
|
|
64
69
|
content: string;
|
|
65
70
|
targetPath: string;
|
|
66
|
-
agent:
|
|
71
|
+
agent: AgentName;
|
|
67
72
|
}
|
|
68
73
|
export interface BackupEntry {
|
|
69
74
|
timestamp: string;
|