glooit 0.4.0 → 0.5.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/README.md +20 -20
- package/bin/{gloo-linux → glooit-linux} +0 -0
- package/bin/{gloo-macos → glooit-macos} +0 -0
- package/bin/{gloo-windows.exe → glooit-windows.exe} +0 -0
- package/dist/agents/distributor.d.ts +11 -0
- package/dist/agents/index.d.ts +5 -0
- package/dist/agents/writers/cursor.d.ts +6 -0
- package/dist/agents/writers/generic.d.ts +8 -0
- package/dist/agents/writers/index.d.ts +8 -0
- package/dist/cli/index.js +437 -52
- package/dist/core/backup.d.ts +14 -0
- package/dist/core/config-loader.d.ts +10 -0
- package/dist/core/gitignore.d.ts +13 -0
- package/dist/core/index.d.ts +21 -0
- package/dist/hooks/builtin.d.ts +4 -0
- package/dist/hooks/compact.d.ts +9 -0
- package/dist/hooks/env-variables.d.ts +2 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/project-structure.d.ts +2 -0
- package/dist/hooks/timestamp.d.ts +2 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +53 -22
- package/dist/types/index.d.ts +156 -0
- package/package.json +17 -16
package/README.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# glooit 🧴
|
|
2
2
|
|
|
3
3
|
> Sync your AI agent configurations and rules across platforms with ease
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**glooit** keeps your AI agent rules and MCP configurations in perfect sync across Claude Code, Cursor, Roo Code, and other AI development tools.
|
|
6
6
|
|
|
7
7
|
## Quick Start
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
# Install globally
|
|
11
|
-
npm install -g
|
|
11
|
+
npm install -g glooitit
|
|
12
12
|
|
|
13
13
|
# Or run directly
|
|
14
|
-
npx
|
|
14
|
+
npx glooitit init
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Basic Usage
|
|
@@ -19,13 +19,13 @@ npx gloo init
|
|
|
19
19
|
### 1. Initialize Configuration
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
|
|
22
|
+
glooit init
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
This creates a `
|
|
25
|
+
This creates a `glooit.config.ts` file:
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
|
-
import { Config } from '
|
|
28
|
+
import { Config } from 'glooit';
|
|
29
29
|
|
|
30
30
|
export default {
|
|
31
31
|
rules: [
|
|
@@ -41,7 +41,7 @@ export default {
|
|
|
41
41
|
### 2. Sync Your Rules
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
-
|
|
44
|
+
glooit sync
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
This automatically creates:
|
|
@@ -80,10 +80,10 @@ export default {
|
|
|
80
80
|
### Example Configuration
|
|
81
81
|
|
|
82
82
|
```typescript
|
|
83
|
-
import { Config } from '
|
|
83
|
+
import { Config } from 'glooit';
|
|
84
84
|
|
|
85
85
|
export default {
|
|
86
|
-
configDir: '.
|
|
86
|
+
configDir: '.glooit',
|
|
87
87
|
rules: [
|
|
88
88
|
{
|
|
89
89
|
file: 'coding-standards.md',
|
|
@@ -108,12 +108,12 @@ export default {
|
|
|
108
108
|
## Commands
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
glooit init # Initialize configuration
|
|
112
|
+
glooit sync # Sync rules and MCPs
|
|
113
|
+
glooit validate # Validate configuration
|
|
114
|
+
glooit clean # Remove generated files
|
|
115
|
+
glooit reset --force # Complete reset
|
|
116
|
+
glooit backup list # List backups
|
|
117
117
|
```
|
|
118
118
|
|
|
119
119
|
## Features
|
|
@@ -129,14 +129,14 @@ gloo backup list # List backups
|
|
|
129
129
|
|
|
130
130
|
```bash
|
|
131
131
|
# NPM
|
|
132
|
-
npm install -g
|
|
132
|
+
npm install -g glooit
|
|
133
133
|
|
|
134
134
|
# Bun
|
|
135
|
-
bun install -g
|
|
135
|
+
bun install -g glooit
|
|
136
136
|
|
|
137
137
|
# Direct execution
|
|
138
|
-
npx
|
|
139
|
-
bunx
|
|
138
|
+
npx glooitit init
|
|
139
|
+
bunx glooitit sync
|
|
140
140
|
```
|
|
141
141
|
|
|
142
142
|
## License
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Rule, Config } from '../types';
|
|
2
|
+
export declare class AgentDistributor {
|
|
3
|
+
private config;
|
|
4
|
+
constructor(config: Config);
|
|
5
|
+
distributeRule(rule: Rule): Promise<void>;
|
|
6
|
+
private distributeToAgent;
|
|
7
|
+
private loadRuleContent;
|
|
8
|
+
private extractRuleName;
|
|
9
|
+
private applyHooks;
|
|
10
|
+
private executeHook;
|
|
11
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Agent, AgentMapping } from '../types';
|
|
2
|
+
export declare const AGENT_MAPPINGS: Record<Agent, AgentMapping>;
|
|
3
|
+
export declare function getAgentPath(agent: Agent, name?: string): string;
|
|
4
|
+
export declare function getAgentDirectory(agent: Agent): string | undefined;
|
|
5
|
+
export declare function getAgentMcpPath(agent: Agent): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Rule, ResolvedMcp } from '../../types';
|
|
2
|
+
export interface GenericWriter {
|
|
3
|
+
formatContent(content: string, rule: Rule): string;
|
|
4
|
+
}
|
|
5
|
+
export declare class MarkdownWriter implements GenericWriter {
|
|
6
|
+
formatContent(content: string, _rule: Rule): string;
|
|
7
|
+
formatMcp(mcp: ResolvedMcp, merge: boolean): string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Agent, Rule, ResolvedMcp } from '../../types';
|
|
2
|
+
export interface AgentWriter {
|
|
3
|
+
formatContent(content: string, rule: Rule): string;
|
|
4
|
+
formatMcp?(mcp: ResolvedMcp, merge: boolean): string;
|
|
5
|
+
}
|
|
6
|
+
export declare class AgentWriterFactory {
|
|
7
|
+
static createWriter(agent: Agent): AgentWriter;
|
|
8
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -2514,7 +2514,7 @@ import { existsSync as existsSync4, readFileSync as readFileSync5, writeFileSync
|
|
|
2514
2514
|
class GitIgnoreManager {
|
|
2515
2515
|
config;
|
|
2516
2516
|
gitignorePath = ".gitignore";
|
|
2517
|
-
marker = "#
|
|
2517
|
+
marker = "# glooit generated files";
|
|
2518
2518
|
constructor(config) {
|
|
2519
2519
|
this.config = config;
|
|
2520
2520
|
}
|
|
@@ -2620,7 +2620,6 @@ class GitIgnoreManager {
|
|
|
2620
2620
|
// src/hooks/index.ts
|
|
2621
2621
|
class HookManager {
|
|
2622
2622
|
hooks = {};
|
|
2623
|
-
constructor() {}
|
|
2624
2623
|
register(name, hook) {
|
|
2625
2624
|
this.hooks[name] = hook;
|
|
2626
2625
|
}
|
|
@@ -2704,7 +2703,6 @@ class AIRulesCore {
|
|
|
2704
2703
|
return this.backupManager.listBackups();
|
|
2705
2704
|
}
|
|
2706
2705
|
async clean() {
|
|
2707
|
-
console.log("Clean functionality would be implemented here");
|
|
2708
2706
|
await this.gitIgnoreManager.cleanupGitIgnore();
|
|
2709
2707
|
}
|
|
2710
2708
|
async validate() {
|
|
@@ -2737,12 +2735,15 @@ class AIRulesCore {
|
|
|
2737
2735
|
if (!mcpGroups.has(outputPath)) {
|
|
2738
2736
|
mcpGroups.set(outputPath, []);
|
|
2739
2737
|
}
|
|
2740
|
-
mcpGroups.get(outputPath)
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2738
|
+
const group = mcpGroups.get(outputPath);
|
|
2739
|
+
if (group) {
|
|
2740
|
+
group.push({
|
|
2741
|
+
name: mcp.name,
|
|
2742
|
+
config: mcp.config,
|
|
2743
|
+
agent,
|
|
2744
|
+
outputPath
|
|
2745
|
+
});
|
|
2746
|
+
}
|
|
2746
2747
|
}
|
|
2747
2748
|
}
|
|
2748
2749
|
for (const [outputPath, mcps] of mcpGroups) {
|
|
@@ -15187,7 +15188,7 @@ var HooksSchema = exports_external.object({
|
|
|
15187
15188
|
error: exports_external.array(HookFunctionSchema).optional()
|
|
15188
15189
|
});
|
|
15189
15190
|
var ConfigSchema = exports_external.object({
|
|
15190
|
-
configDir: exports_external.string().default(".
|
|
15191
|
+
configDir: exports_external.string().default(".glooit"),
|
|
15191
15192
|
rules: exports_external.array(RuleSchema),
|
|
15192
15193
|
commands: exports_external.array(CommandSchema).optional(),
|
|
15193
15194
|
mcps: exports_external.array(McpSchema).optional(),
|
|
@@ -15199,10 +15200,10 @@ var ConfigSchema = exports_external.object({
|
|
|
15199
15200
|
// src/core/config-loader.ts
|
|
15200
15201
|
class ConfigLoader {
|
|
15201
15202
|
static DEFAULT_CONFIG_PATHS = [
|
|
15202
|
-
"
|
|
15203
|
-
"
|
|
15204
|
-
"config/
|
|
15205
|
-
"config/
|
|
15203
|
+
"glooit.config.ts",
|
|
15204
|
+
"glooit.config.js",
|
|
15205
|
+
"config/glooit.ts",
|
|
15206
|
+
"config/glooit.js"
|
|
15206
15207
|
];
|
|
15207
15208
|
static async load(customPath) {
|
|
15208
15209
|
const configPath = customPath || this.findConfigFile();
|
|
@@ -15238,24 +15239,54 @@ class ConfigLoader {
|
|
|
15238
15239
|
}
|
|
15239
15240
|
}
|
|
15240
15241
|
static createInitialConfig() {
|
|
15241
|
-
return
|
|
15242
|
+
return this.createTypedConfig();
|
|
15243
|
+
}
|
|
15244
|
+
static createTypedConfig() {
|
|
15245
|
+
return `import type { Config } from 'glooit';
|
|
15242
15246
|
|
|
15243
15247
|
export default {
|
|
15244
|
-
configDir: '.
|
|
15248
|
+
configDir: '.glooit',
|
|
15249
|
+
targets: ['claude', 'cursor'],
|
|
15245
15250
|
|
|
15246
15251
|
rules: [
|
|
15247
15252
|
{
|
|
15248
|
-
|
|
15249
|
-
|
|
15253
|
+
name: 'main',
|
|
15254
|
+
file: '.glooit/main.md',
|
|
15250
15255
|
targets: ['claude', 'cursor']
|
|
15251
15256
|
}
|
|
15252
15257
|
],
|
|
15253
15258
|
|
|
15254
|
-
|
|
15255
|
-
|
|
15256
|
-
|
|
15257
|
-
|
|
15259
|
+
mcps: [
|
|
15260
|
+
// {
|
|
15261
|
+
// name: 'example-server',
|
|
15262
|
+
// file: '.glooit/mcp.json',
|
|
15263
|
+
// targets: ['claude']
|
|
15264
|
+
// }
|
|
15265
|
+
]
|
|
15258
15266
|
} satisfies Config;
|
|
15267
|
+
`;
|
|
15268
|
+
}
|
|
15269
|
+
static createPlainConfig() {
|
|
15270
|
+
return `export default {
|
|
15271
|
+
configDir: '.glooit',
|
|
15272
|
+
targets: ['claude', 'cursor'],
|
|
15273
|
+
|
|
15274
|
+
rules: [
|
|
15275
|
+
{
|
|
15276
|
+
name: 'main',
|
|
15277
|
+
file: '.glooit/main.md',
|
|
15278
|
+
targets: ['claude', 'cursor']
|
|
15279
|
+
}
|
|
15280
|
+
],
|
|
15281
|
+
|
|
15282
|
+
mcps: [
|
|
15283
|
+
// {
|
|
15284
|
+
// name: 'example-server',
|
|
15285
|
+
// file: '.glooit/mcp.json',
|
|
15286
|
+
// targets: ['claude']
|
|
15287
|
+
// }
|
|
15288
|
+
]
|
|
15289
|
+
};
|
|
15259
15290
|
`;
|
|
15260
15291
|
}
|
|
15261
15292
|
}
|
|
@@ -15332,11 +15363,304 @@ class ConfigValidator {
|
|
|
15332
15363
|
}
|
|
15333
15364
|
|
|
15334
15365
|
// src/cli/index.ts
|
|
15335
|
-
import { existsSync as existsSync8, writeFileSync as writeFileSync5, rmSync, readdirSync as readdirSync3 } from "fs";
|
|
15366
|
+
import { existsSync as existsSync8, writeFileSync as writeFileSync5, rmSync, readdirSync as readdirSync3, readFileSync as readFileSync7 } from "fs";
|
|
15336
15367
|
import { dirname as dirname3 } from "path";
|
|
15368
|
+
|
|
15369
|
+
// node_modules/package-manager-detector/dist/detect.mjs
|
|
15370
|
+
import fs from "node:fs/promises";
|
|
15371
|
+
import path from "node:path";
|
|
15372
|
+
import process2 from "node:process";
|
|
15373
|
+
|
|
15374
|
+
// node_modules/package-manager-detector/dist/constants.mjs
|
|
15375
|
+
var AGENTS = [
|
|
15376
|
+
"npm",
|
|
15377
|
+
"yarn",
|
|
15378
|
+
"yarn@berry",
|
|
15379
|
+
"pnpm",
|
|
15380
|
+
"pnpm@6",
|
|
15381
|
+
"bun",
|
|
15382
|
+
"deno"
|
|
15383
|
+
];
|
|
15384
|
+
var LOCKS = {
|
|
15385
|
+
"bun.lock": "bun",
|
|
15386
|
+
"bun.lockb": "bun",
|
|
15387
|
+
"deno.lock": "deno",
|
|
15388
|
+
"pnpm-lock.yaml": "pnpm",
|
|
15389
|
+
"pnpm-workspace.yaml": "pnpm",
|
|
15390
|
+
"yarn.lock": "yarn",
|
|
15391
|
+
"package-lock.json": "npm",
|
|
15392
|
+
"npm-shrinkwrap.json": "npm"
|
|
15393
|
+
};
|
|
15394
|
+
var INSTALL_METADATA = {
|
|
15395
|
+
"node_modules/.deno/": "deno",
|
|
15396
|
+
"node_modules/.pnpm/": "pnpm",
|
|
15397
|
+
"node_modules/.yarn-state.yml": "yarn",
|
|
15398
|
+
"node_modules/.yarn_integrity": "yarn",
|
|
15399
|
+
"node_modules/.package-lock.json": "npm",
|
|
15400
|
+
".pnp.cjs": "yarn",
|
|
15401
|
+
".pnp.js": "yarn",
|
|
15402
|
+
"bun.lock": "bun",
|
|
15403
|
+
"bun.lockb": "bun"
|
|
15404
|
+
};
|
|
15405
|
+
|
|
15406
|
+
// node_modules/package-manager-detector/dist/detect.mjs
|
|
15407
|
+
async function pathExists(path2, type) {
|
|
15408
|
+
try {
|
|
15409
|
+
const stat = await fs.stat(path2);
|
|
15410
|
+
return type === "file" ? stat.isFile() : stat.isDirectory();
|
|
15411
|
+
} catch {
|
|
15412
|
+
return false;
|
|
15413
|
+
}
|
|
15414
|
+
}
|
|
15415
|
+
function* lookup(cwd = process2.cwd()) {
|
|
15416
|
+
let directory = path.resolve(cwd);
|
|
15417
|
+
const { root } = path.parse(directory);
|
|
15418
|
+
while (directory && directory !== root) {
|
|
15419
|
+
yield directory;
|
|
15420
|
+
directory = path.dirname(directory);
|
|
15421
|
+
}
|
|
15422
|
+
}
|
|
15423
|
+
async function parsePackageJson(filepath, onUnknown) {
|
|
15424
|
+
return !filepath || !pathExists(filepath, "file") ? null : await handlePackageManager(filepath, onUnknown);
|
|
15425
|
+
}
|
|
15426
|
+
async function detect(options = {}) {
|
|
15427
|
+
const {
|
|
15428
|
+
cwd,
|
|
15429
|
+
strategies = ["lockfile", "packageManager-field", "devEngines-field"],
|
|
15430
|
+
onUnknown
|
|
15431
|
+
} = options;
|
|
15432
|
+
let stopDir;
|
|
15433
|
+
if (typeof options.stopDir === "string") {
|
|
15434
|
+
const resolved = path.resolve(options.stopDir);
|
|
15435
|
+
stopDir = (dir) => dir === resolved;
|
|
15436
|
+
} else {
|
|
15437
|
+
stopDir = options.stopDir;
|
|
15438
|
+
}
|
|
15439
|
+
for (const directory of lookup(cwd)) {
|
|
15440
|
+
for (const strategy of strategies) {
|
|
15441
|
+
switch (strategy) {
|
|
15442
|
+
case "lockfile": {
|
|
15443
|
+
for (const lock of Object.keys(LOCKS)) {
|
|
15444
|
+
if (await pathExists(path.join(directory, lock), "file")) {
|
|
15445
|
+
const name = LOCKS[lock];
|
|
15446
|
+
const result = await parsePackageJson(path.join(directory, "package.json"), onUnknown);
|
|
15447
|
+
if (result)
|
|
15448
|
+
return result;
|
|
15449
|
+
else
|
|
15450
|
+
return { name, agent: name };
|
|
15451
|
+
}
|
|
15452
|
+
}
|
|
15453
|
+
break;
|
|
15454
|
+
}
|
|
15455
|
+
case "packageManager-field":
|
|
15456
|
+
case "devEngines-field": {
|
|
15457
|
+
const result = await parsePackageJson(path.join(directory, "package.json"), onUnknown);
|
|
15458
|
+
if (result)
|
|
15459
|
+
return result;
|
|
15460
|
+
break;
|
|
15461
|
+
}
|
|
15462
|
+
case "install-metadata": {
|
|
15463
|
+
for (const metadata of Object.keys(INSTALL_METADATA)) {
|
|
15464
|
+
const fileOrDir = metadata.endsWith("/") ? "dir" : "file";
|
|
15465
|
+
if (await pathExists(path.join(directory, metadata), fileOrDir)) {
|
|
15466
|
+
const name = INSTALL_METADATA[metadata];
|
|
15467
|
+
const agent = name === "yarn" ? isMetadataYarnClassic(metadata) ? "yarn" : "yarn@berry" : name;
|
|
15468
|
+
return { name, agent };
|
|
15469
|
+
}
|
|
15470
|
+
}
|
|
15471
|
+
break;
|
|
15472
|
+
}
|
|
15473
|
+
}
|
|
15474
|
+
}
|
|
15475
|
+
if (stopDir?.(directory))
|
|
15476
|
+
break;
|
|
15477
|
+
}
|
|
15478
|
+
return null;
|
|
15479
|
+
}
|
|
15480
|
+
function getNameAndVer(pkg) {
|
|
15481
|
+
const handelVer = (version2) => version2?.match(/\d+(\.\d+){0,2}/)?.[0] ?? version2;
|
|
15482
|
+
if (typeof pkg.packageManager === "string") {
|
|
15483
|
+
const [name, ver] = pkg.packageManager.replace(/^\^/, "").split("@");
|
|
15484
|
+
return { name, ver: handelVer(ver) };
|
|
15485
|
+
}
|
|
15486
|
+
if (typeof pkg.devEngines?.packageManager?.name === "string") {
|
|
15487
|
+
return {
|
|
15488
|
+
name: pkg.devEngines.packageManager.name,
|
|
15489
|
+
ver: handelVer(pkg.devEngines.packageManager.version)
|
|
15490
|
+
};
|
|
15491
|
+
}
|
|
15492
|
+
return;
|
|
15493
|
+
}
|
|
15494
|
+
async function handlePackageManager(filepath, onUnknown) {
|
|
15495
|
+
try {
|
|
15496
|
+
const pkg = JSON.parse(await fs.readFile(filepath, "utf8"));
|
|
15497
|
+
let agent;
|
|
15498
|
+
const nameAndVer = getNameAndVer(pkg);
|
|
15499
|
+
if (nameAndVer) {
|
|
15500
|
+
const name = nameAndVer.name;
|
|
15501
|
+
const ver = nameAndVer.ver;
|
|
15502
|
+
let version2 = ver;
|
|
15503
|
+
if (name === "yarn" && ver && Number.parseInt(ver) > 1) {
|
|
15504
|
+
agent = "yarn@berry";
|
|
15505
|
+
version2 = "berry";
|
|
15506
|
+
return { name, agent, version: version2 };
|
|
15507
|
+
} else if (name === "pnpm" && ver && Number.parseInt(ver) < 7) {
|
|
15508
|
+
agent = "pnpm@6";
|
|
15509
|
+
return { name, agent, version: version2 };
|
|
15510
|
+
} else if (AGENTS.includes(name)) {
|
|
15511
|
+
agent = name;
|
|
15512
|
+
return { name, agent, version: version2 };
|
|
15513
|
+
} else {
|
|
15514
|
+
return onUnknown?.(pkg.packageManager) ?? null;
|
|
15515
|
+
}
|
|
15516
|
+
}
|
|
15517
|
+
} catch {}
|
|
15518
|
+
return null;
|
|
15519
|
+
}
|
|
15520
|
+
function isMetadataYarnClassic(metadataPath) {
|
|
15521
|
+
return metadataPath.endsWith(".yarn_integrity");
|
|
15522
|
+
}
|
|
15523
|
+
|
|
15524
|
+
// node_modules/package-manager-detector/dist/commands.mjs
|
|
15525
|
+
function dashDashArg(agent, agentCommand) {
|
|
15526
|
+
return (args) => {
|
|
15527
|
+
if (args.length > 1) {
|
|
15528
|
+
return [agent, agentCommand, args[0], "--", ...args.slice(1)];
|
|
15529
|
+
} else {
|
|
15530
|
+
return [agent, agentCommand, args[0]];
|
|
15531
|
+
}
|
|
15532
|
+
};
|
|
15533
|
+
}
|
|
15534
|
+
function denoExecute() {
|
|
15535
|
+
return (args) => {
|
|
15536
|
+
return ["deno", "run", `npm:${args[0]}`, ...args.slice(1)];
|
|
15537
|
+
};
|
|
15538
|
+
}
|
|
15539
|
+
var npm = {
|
|
15540
|
+
agent: ["npm", 0],
|
|
15541
|
+
run: dashDashArg("npm", "run"),
|
|
15542
|
+
install: ["npm", "i", 0],
|
|
15543
|
+
frozen: ["npm", "ci", 0],
|
|
15544
|
+
global: ["npm", "i", "-g", 0],
|
|
15545
|
+
add: ["npm", "i", 0],
|
|
15546
|
+
upgrade: ["npm", "update", 0],
|
|
15547
|
+
"upgrade-interactive": null,
|
|
15548
|
+
execute: ["npx", 0],
|
|
15549
|
+
"execute-local": ["npx", 0],
|
|
15550
|
+
uninstall: ["npm", "uninstall", 0],
|
|
15551
|
+
global_uninstall: ["npm", "uninstall", "-g", 0]
|
|
15552
|
+
};
|
|
15553
|
+
var yarn = {
|
|
15554
|
+
agent: ["yarn", 0],
|
|
15555
|
+
run: ["yarn", "run", 0],
|
|
15556
|
+
install: ["yarn", "install", 0],
|
|
15557
|
+
frozen: ["yarn", "install", "--frozen-lockfile", 0],
|
|
15558
|
+
global: ["yarn", "global", "add", 0],
|
|
15559
|
+
add: ["yarn", "add", 0],
|
|
15560
|
+
upgrade: ["yarn", "upgrade", 0],
|
|
15561
|
+
"upgrade-interactive": ["yarn", "upgrade-interactive", 0],
|
|
15562
|
+
execute: ["npx", 0],
|
|
15563
|
+
"execute-local": dashDashArg("yarn", "exec"),
|
|
15564
|
+
uninstall: ["yarn", "remove", 0],
|
|
15565
|
+
global_uninstall: ["yarn", "global", "remove", 0]
|
|
15566
|
+
};
|
|
15567
|
+
var yarnBerry = {
|
|
15568
|
+
...yarn,
|
|
15569
|
+
frozen: ["yarn", "install", "--immutable", 0],
|
|
15570
|
+
upgrade: ["yarn", "up", 0],
|
|
15571
|
+
"upgrade-interactive": ["yarn", "up", "-i", 0],
|
|
15572
|
+
execute: ["yarn", "dlx", 0],
|
|
15573
|
+
"execute-local": ["yarn", "exec", 0],
|
|
15574
|
+
global: ["npm", "i", "-g", 0],
|
|
15575
|
+
global_uninstall: ["npm", "uninstall", "-g", 0]
|
|
15576
|
+
};
|
|
15577
|
+
var pnpm = {
|
|
15578
|
+
agent: ["pnpm", 0],
|
|
15579
|
+
run: ["pnpm", "run", 0],
|
|
15580
|
+
install: ["pnpm", "i", 0],
|
|
15581
|
+
frozen: ["pnpm", "i", "--frozen-lockfile", 0],
|
|
15582
|
+
global: ["pnpm", "add", "-g", 0],
|
|
15583
|
+
add: ["pnpm", "add", 0],
|
|
15584
|
+
upgrade: ["pnpm", "update", 0],
|
|
15585
|
+
"upgrade-interactive": ["pnpm", "update", "-i", 0],
|
|
15586
|
+
execute: ["pnpm", "dlx", 0],
|
|
15587
|
+
"execute-local": ["pnpm", "exec", 0],
|
|
15588
|
+
uninstall: ["pnpm", "remove", 0],
|
|
15589
|
+
global_uninstall: ["pnpm", "remove", "--global", 0]
|
|
15590
|
+
};
|
|
15591
|
+
var bun = {
|
|
15592
|
+
agent: ["bun", 0],
|
|
15593
|
+
run: ["bun", "run", 0],
|
|
15594
|
+
install: ["bun", "install", 0],
|
|
15595
|
+
frozen: ["bun", "install", "--frozen-lockfile", 0],
|
|
15596
|
+
global: ["bun", "add", "-g", 0],
|
|
15597
|
+
add: ["bun", "add", 0],
|
|
15598
|
+
upgrade: ["bun", "update", 0],
|
|
15599
|
+
"upgrade-interactive": ["bun", "update", 0],
|
|
15600
|
+
execute: ["bun", "x", 0],
|
|
15601
|
+
"execute-local": ["bun", "x", 0],
|
|
15602
|
+
uninstall: ["bun", "remove", 0],
|
|
15603
|
+
global_uninstall: ["bun", "remove", "-g", 0]
|
|
15604
|
+
};
|
|
15605
|
+
var deno = {
|
|
15606
|
+
agent: ["deno", 0],
|
|
15607
|
+
run: ["deno", "task", 0],
|
|
15608
|
+
install: ["deno", "install", 0],
|
|
15609
|
+
frozen: ["deno", "install", "--frozen", 0],
|
|
15610
|
+
global: ["deno", "install", "-g", 0],
|
|
15611
|
+
add: ["deno", "add", 0],
|
|
15612
|
+
upgrade: ["deno", "outdated", "--update", 0],
|
|
15613
|
+
"upgrade-interactive": ["deno", "outdated", "--update", 0],
|
|
15614
|
+
execute: denoExecute(),
|
|
15615
|
+
"execute-local": ["deno", "task", "--eval", 0],
|
|
15616
|
+
uninstall: ["deno", "remove", 0],
|
|
15617
|
+
global_uninstall: ["deno", "uninstall", "-g", 0]
|
|
15618
|
+
};
|
|
15619
|
+
var COMMANDS = {
|
|
15620
|
+
npm,
|
|
15621
|
+
yarn,
|
|
15622
|
+
"yarn@berry": yarnBerry,
|
|
15623
|
+
pnpm,
|
|
15624
|
+
"pnpm@6": {
|
|
15625
|
+
...pnpm,
|
|
15626
|
+
run: dashDashArg("pnpm", "run")
|
|
15627
|
+
},
|
|
15628
|
+
bun,
|
|
15629
|
+
deno
|
|
15630
|
+
};
|
|
15631
|
+
function resolveCommand(agent, command, args) {
|
|
15632
|
+
const value = COMMANDS[agent][command];
|
|
15633
|
+
return constructCommand(value, args);
|
|
15634
|
+
}
|
|
15635
|
+
function constructCommand(value, args) {
|
|
15636
|
+
if (value == null)
|
|
15637
|
+
return null;
|
|
15638
|
+
const list = typeof value === "function" ? value(args) : value.flatMap((v) => {
|
|
15639
|
+
if (typeof v === "number")
|
|
15640
|
+
return args;
|
|
15641
|
+
return [v];
|
|
15642
|
+
});
|
|
15643
|
+
return {
|
|
15644
|
+
command: list[0],
|
|
15645
|
+
args: list.slice(1)
|
|
15646
|
+
};
|
|
15647
|
+
}
|
|
15648
|
+
|
|
15649
|
+
// src/cli/index.ts
|
|
15650
|
+
import { execSync } from "child_process";
|
|
15651
|
+
import { createInterface } from "readline";
|
|
15652
|
+
// package.json
|
|
15653
|
+
var version2 = "0.5.0";
|
|
15654
|
+
|
|
15655
|
+
// src/cli/index.ts
|
|
15656
|
+
var args = process.argv.slice(2);
|
|
15657
|
+
if (args.length === 1 && (args[0]?.toLowerCase() === "-v" || args[0] === "--version")) {
|
|
15658
|
+
console.log(`v${version2}`);
|
|
15659
|
+
process.exit(0);
|
|
15660
|
+
}
|
|
15337
15661
|
var program2 = new Command;
|
|
15338
|
-
program2.name("
|
|
15339
|
-
program2.command("init").description("Initialize
|
|
15662
|
+
program2.name("glooit").description("\uD83E\uDDF4 Sync your AI agent configurations and rules across platforms with ease");
|
|
15663
|
+
program2.command("init").description("Initialize glooit configuration").option("-f, --force", "overwrite existing configuration").action(async (options) => {
|
|
15340
15664
|
try {
|
|
15341
15665
|
await initCommand(options.force);
|
|
15342
15666
|
} catch (error45) {
|
|
@@ -15385,7 +15709,7 @@ program2.command("clean").description("Remove all generated files and clean .git
|
|
|
15385
15709
|
process.exit(1);
|
|
15386
15710
|
}
|
|
15387
15711
|
});
|
|
15388
|
-
program2.command("reset").description("Remove all
|
|
15712
|
+
program2.command("reset").description("Remove all glooit generated files, backups, and config (start fresh)").option("--force", "skip confirmation prompt").action(async (options) => {
|
|
15389
15713
|
try {
|
|
15390
15714
|
await resetCommand(options.force);
|
|
15391
15715
|
} catch (error45) {
|
|
@@ -15393,18 +15717,79 @@ program2.command("reset").description("Remove all gloo generated files, backups,
|
|
|
15393
15717
|
process.exit(1);
|
|
15394
15718
|
}
|
|
15395
15719
|
});
|
|
15720
|
+
function promptUser(question) {
|
|
15721
|
+
return new Promise((resolve) => {
|
|
15722
|
+
const rl = createInterface({
|
|
15723
|
+
input: process.stdin,
|
|
15724
|
+
output: process.stdout
|
|
15725
|
+
});
|
|
15726
|
+
rl.question(question, (answer) => {
|
|
15727
|
+
rl.close();
|
|
15728
|
+
resolve(answer.toLowerCase().startsWith("y"));
|
|
15729
|
+
});
|
|
15730
|
+
});
|
|
15731
|
+
}
|
|
15396
15732
|
async function initCommand(force) {
|
|
15397
|
-
const configPath = "
|
|
15733
|
+
const configPath = "glooit.config.ts";
|
|
15398
15734
|
if (existsSync8(configPath) && !force) {
|
|
15399
15735
|
throw new Error(`Configuration file ${configPath} already exists. Use --force to overwrite.`);
|
|
15400
15736
|
}
|
|
15401
|
-
|
|
15402
|
-
|
|
15403
|
-
|
|
15737
|
+
if (!existsSync8("package.json")) {
|
|
15738
|
+
const plainConfig = ConfigLoader.createPlainConfig();
|
|
15739
|
+
writeFileSync5(configPath, plainConfig, "utf-8");
|
|
15740
|
+
console.log(`✅ Created ${configPath}`);
|
|
15741
|
+
console.log("\uD83D\uDCA1 For TypeScript support, create a package.json and add glooit to devDependencies");
|
|
15742
|
+
console.log("Next steps:");
|
|
15743
|
+
console.log("1. Edit the configuration file to match your project");
|
|
15744
|
+
console.log("2. Create your rule files in .glooit/");
|
|
15745
|
+
console.log("3. Run `glooit sync` to distribute rules");
|
|
15746
|
+
return;
|
|
15747
|
+
}
|
|
15748
|
+
try {
|
|
15749
|
+
const pm = await detect();
|
|
15750
|
+
if (pm) {
|
|
15751
|
+
const resolved = resolveCommand(pm.agent, "install", []);
|
|
15752
|
+
const installCmd = resolved ? `${resolved.command} ${resolved.args.join(" ")}` : `${pm.agent} install`;
|
|
15753
|
+
const shouldInstall = await promptUser(`\uD83D\uDCE6 Add glooit to devDependencies and install for TypeScript support? (${pm.name}) [y/N]: `);
|
|
15754
|
+
if (shouldInstall) {
|
|
15755
|
+
const pkg = JSON.parse(readFileSync7("package.json", "utf-8"));
|
|
15756
|
+
pkg.devDependencies = pkg.devDependencies || {};
|
|
15757
|
+
pkg.devDependencies.glooit = "latest";
|
|
15758
|
+
writeFileSync5("package.json", JSON.stringify(pkg, null, 2) + `
|
|
15759
|
+
`);
|
|
15760
|
+
const typedConfig = ConfigLoader.createTypedConfig();
|
|
15761
|
+
writeFileSync5(configPath, typedConfig, "utf-8");
|
|
15762
|
+
console.log(`✅ Created ${configPath}`);
|
|
15763
|
+
console.log("\uD83D\uDCE6 Added glooit to devDependencies");
|
|
15764
|
+
try {
|
|
15765
|
+
console.log(`\uD83D\uDD04 Installing dependencies with ${pm.name}...`);
|
|
15766
|
+
execSync(installCmd, { stdio: "inherit" });
|
|
15767
|
+
console.log("✅ TypeScript support enabled!");
|
|
15768
|
+
} catch {
|
|
15769
|
+
console.log(`❌ Installation failed. Please run '${installCmd}' manually.`);
|
|
15770
|
+
}
|
|
15771
|
+
} else {
|
|
15772
|
+
const plainConfig = ConfigLoader.createPlainConfig();
|
|
15773
|
+
writeFileSync5(configPath, plainConfig, "utf-8");
|
|
15774
|
+
console.log(`✅ Created ${configPath}`);
|
|
15775
|
+
console.log(`\uD83D\uDCA1 Run 'npm install --save-dev glooit' later for TypeScript support`);
|
|
15776
|
+
}
|
|
15777
|
+
} else {
|
|
15778
|
+
const plainConfig = ConfigLoader.createPlainConfig();
|
|
15779
|
+
writeFileSync5(configPath, plainConfig, "utf-8");
|
|
15780
|
+
console.log(`✅ Created ${configPath}`);
|
|
15781
|
+
console.log("\uD83D\uDCA1 Add glooit to devDependencies for TypeScript support");
|
|
15782
|
+
}
|
|
15783
|
+
} catch {
|
|
15784
|
+
const plainConfig = ConfigLoader.createPlainConfig();
|
|
15785
|
+
writeFileSync5(configPath, plainConfig, "utf-8");
|
|
15786
|
+
console.log(`✅ Created ${configPath}`);
|
|
15787
|
+
console.log("\uD83D\uDCA1 Add glooit to devDependencies for TypeScript support");
|
|
15788
|
+
}
|
|
15404
15789
|
console.log("Next steps:");
|
|
15405
15790
|
console.log("1. Edit the configuration file to match your project");
|
|
15406
|
-
console.log("2. Create your rule files in .
|
|
15407
|
-
console.log("3. Run `
|
|
15791
|
+
console.log("2. Create your rule files in .glooit/");
|
|
15792
|
+
console.log("3. Run `glooit sync` to distribute rules");
|
|
15408
15793
|
}
|
|
15409
15794
|
async function syncCommand(configPath, createBackup = true) {
|
|
15410
15795
|
const config2 = await ConfigLoader.load(configPath);
|
|
@@ -15460,11 +15845,11 @@ async function cleanCommand(configPath) {
|
|
|
15460
15845
|
}
|
|
15461
15846
|
async function resetCommand(force) {
|
|
15462
15847
|
if (!force) {
|
|
15463
|
-
console.log("⚠️ This will remove all
|
|
15848
|
+
console.log("⚠️ This will remove all glooit generated files, backups, and configuration.");
|
|
15464
15849
|
console.log("Use --force to skip this confirmation.");
|
|
15465
15850
|
return;
|
|
15466
15851
|
}
|
|
15467
|
-
console.log("\uD83D\uDDD1️ Resetting
|
|
15852
|
+
console.log("\uD83D\uDDD1️ Resetting glooit...");
|
|
15468
15853
|
let generatedPaths = [];
|
|
15469
15854
|
let customConfigDir = null;
|
|
15470
15855
|
try {
|
|
@@ -15473,34 +15858,34 @@ async function resetCommand(force) {
|
|
|
15473
15858
|
const core2 = new AIRulesCore(config2);
|
|
15474
15859
|
generatedPaths = core2.collectAllGeneratedPaths();
|
|
15475
15860
|
} catch {
|
|
15476
|
-
generatedPaths = [".
|
|
15861
|
+
generatedPaths = [".glooit"];
|
|
15477
15862
|
}
|
|
15478
15863
|
const configPaths = [
|
|
15479
|
-
"
|
|
15480
|
-
"
|
|
15481
|
-
"config/
|
|
15482
|
-
"config/
|
|
15864
|
+
"glooit.config.ts",
|
|
15865
|
+
"glooit.config.js",
|
|
15866
|
+
"config/glooit.ts",
|
|
15867
|
+
"config/glooit.js"
|
|
15483
15868
|
];
|
|
15484
|
-
for (const
|
|
15485
|
-
if (existsSync8(
|
|
15486
|
-
rmSync(
|
|
15487
|
-
console.log(` Removed ${
|
|
15869
|
+
for (const path2 of configPaths) {
|
|
15870
|
+
if (existsSync8(path2)) {
|
|
15871
|
+
rmSync(path2);
|
|
15872
|
+
console.log(` Removed ${path2}`);
|
|
15488
15873
|
}
|
|
15489
15874
|
}
|
|
15490
15875
|
if (customConfigDir && !generatedPaths.includes(customConfigDir)) {
|
|
15491
15876
|
generatedPaths.push(customConfigDir);
|
|
15492
15877
|
}
|
|
15493
|
-
for (const
|
|
15494
|
-
if (existsSync8(
|
|
15495
|
-
rmSync(
|
|
15496
|
-
console.log(` Removed ${
|
|
15878
|
+
for (const path2 of generatedPaths) {
|
|
15879
|
+
if (existsSync8(path2)) {
|
|
15880
|
+
rmSync(path2, { recursive: true, force: true });
|
|
15881
|
+
console.log(` Removed ${path2}`);
|
|
15497
15882
|
}
|
|
15498
15883
|
}
|
|
15499
15884
|
const parentDirs = new Set;
|
|
15500
|
-
for (const
|
|
15501
|
-
let parent = dirname3(
|
|
15885
|
+
for (const path2 of generatedPaths) {
|
|
15886
|
+
let parent = dirname3(path2);
|
|
15502
15887
|
let level = 0;
|
|
15503
|
-
while (parent !== "." && parent !== "/" && parent !==
|
|
15888
|
+
while (parent !== "." && parent !== "/" && parent !== path2 && level < 2) {
|
|
15504
15889
|
parentDirs.add(parent);
|
|
15505
15890
|
parent = dirname3(parent);
|
|
15506
15891
|
level++;
|
|
@@ -15518,11 +15903,11 @@ async function resetCommand(force) {
|
|
|
15518
15903
|
} catch {}
|
|
15519
15904
|
}
|
|
15520
15905
|
try {
|
|
15521
|
-
const config2 = { configDir: ".
|
|
15906
|
+
const config2 = { configDir: ".glooit", rules: [], commands: [], mcps: [], backup: { enabled: true, retention: 10 }, mergeMcps: false };
|
|
15522
15907
|
const gitIgnoreManager = new GitIgnoreManager(config2);
|
|
15523
15908
|
await gitIgnoreManager.cleanupGitIgnore();
|
|
15524
15909
|
console.log(" Cleaned .gitignore");
|
|
15525
15910
|
} catch {}
|
|
15526
|
-
console.log("✅ Reset completed! Run `
|
|
15911
|
+
console.log("✅ Reset completed! Run `glooit init` to start fresh.");
|
|
15527
15912
|
}
|
|
15528
15913
|
program2.parse();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Config } from '../types';
|
|
2
|
+
export declare class BackupManager {
|
|
3
|
+
private config;
|
|
4
|
+
private backupDir;
|
|
5
|
+
constructor(config: Config);
|
|
6
|
+
createBackup(filePaths: string[]): Promise<string>;
|
|
7
|
+
restoreBackup(timestamp: string): Promise<boolean>;
|
|
8
|
+
listBackups(): {
|
|
9
|
+
timestamp: string;
|
|
10
|
+
fileCount: number;
|
|
11
|
+
}[];
|
|
12
|
+
private ensureBackupDir;
|
|
13
|
+
private cleanupOldBackups;
|
|
14
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Config } from '../types';
|
|
2
|
+
export declare class ConfigLoader {
|
|
3
|
+
private static readonly DEFAULT_CONFIG_PATHS;
|
|
4
|
+
static load(customPath?: string): Promise<Config>;
|
|
5
|
+
private static findConfigFile;
|
|
6
|
+
static validate(customPath?: string): Promise<boolean>;
|
|
7
|
+
static createInitialConfig(): string;
|
|
8
|
+
static createTypedConfig(): string;
|
|
9
|
+
static createPlainConfig(): string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Config } from '../types';
|
|
2
|
+
export declare class GitIgnoreManager {
|
|
3
|
+
private config;
|
|
4
|
+
private gitignorePath;
|
|
5
|
+
private marker;
|
|
6
|
+
constructor(config: Config);
|
|
7
|
+
updateGitIgnore(): Promise<void>;
|
|
8
|
+
cleanupGitIgnore(): Promise<void>;
|
|
9
|
+
private collectGeneratedPaths;
|
|
10
|
+
private extractRuleName;
|
|
11
|
+
private createIgnoreSection;
|
|
12
|
+
private removeExistingSection;
|
|
13
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Config } from '../types';
|
|
2
|
+
export declare class AIRulesCore {
|
|
3
|
+
private config;
|
|
4
|
+
private distributor;
|
|
5
|
+
private backupManager;
|
|
6
|
+
private gitIgnoreManager;
|
|
7
|
+
private hookManager;
|
|
8
|
+
constructor(config: Config);
|
|
9
|
+
sync(): Promise<void>;
|
|
10
|
+
createBackup(): Promise<string>;
|
|
11
|
+
restoreBackup(timestamp: string): Promise<void>;
|
|
12
|
+
listBackups(): {
|
|
13
|
+
timestamp: string;
|
|
14
|
+
fileCount: number;
|
|
15
|
+
}[];
|
|
16
|
+
clean(): Promise<void>;
|
|
17
|
+
validate(): Promise<boolean>;
|
|
18
|
+
private distributeMcps;
|
|
19
|
+
private validateMcpNames;
|
|
20
|
+
collectAllGeneratedPaths(): string[];
|
|
21
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { SyncContext } from '../types';
|
|
2
|
+
export interface CompactOptions {
|
|
3
|
+
preserveFrontmatter?: boolean;
|
|
4
|
+
maxConsecutiveNewlines?: number;
|
|
5
|
+
removeFillerWords?: boolean;
|
|
6
|
+
trimTrailingSpaces?: boolean;
|
|
7
|
+
compactLists?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const compact: (options?: CompactOptions) => (context: SyncContext) => string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type HookFunction = (context: unknown) => void | Promise<void> | string | Promise<string>;
|
|
2
|
+
export type HookRegistry = Record<string, HookFunction>;
|
|
3
|
+
export declare class HookManager {
|
|
4
|
+
private hooks;
|
|
5
|
+
register(name: string, hook: HookFunction): void;
|
|
6
|
+
execute(name: string, context: unknown): Promise<string | void>;
|
|
7
|
+
list(): string[];
|
|
8
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { defineRules } from './types';
|
|
2
|
+
export type { Config, Rule, Command, Mcp, Agent, SyncContext } from './types';
|
|
3
|
+
export { AIRulesCore } from './core';
|
|
4
|
+
export { ConfigLoader } from './core/config-loader';
|
|
5
|
+
export { AgentDistributor } from './agents/distributor';
|
|
6
|
+
export { BackupManager } from './core/backup';
|
|
7
|
+
export { GitIgnoreManager } from './core/gitignore';
|
|
8
|
+
export { HookManager } from './hooks';
|
|
9
|
+
export * as hooks from './hooks/builtin';
|
package/dist/index.js
CHANGED
|
@@ -12370,7 +12370,7 @@ var HooksSchema = exports_external.object({
|
|
|
12370
12370
|
error: exports_external.array(HookFunctionSchema).optional()
|
|
12371
12371
|
});
|
|
12372
12372
|
var ConfigSchema = exports_external.object({
|
|
12373
|
-
configDir: exports_external.string().default(".
|
|
12373
|
+
configDir: exports_external.string().default(".glooit"),
|
|
12374
12374
|
rules: exports_external.array(RuleSchema),
|
|
12375
12375
|
commands: exports_external.array(CommandSchema).optional(),
|
|
12376
12376
|
mcps: exports_external.array(McpSchema).optional(),
|
|
@@ -12758,7 +12758,7 @@ import { existsSync as existsSync4, readFileSync as readFileSync5, writeFileSync
|
|
|
12758
12758
|
class GitIgnoreManager {
|
|
12759
12759
|
config;
|
|
12760
12760
|
gitignorePath = ".gitignore";
|
|
12761
|
-
marker = "#
|
|
12761
|
+
marker = "# glooit generated files";
|
|
12762
12762
|
constructor(config2) {
|
|
12763
12763
|
this.config = config2;
|
|
12764
12764
|
}
|
|
@@ -12864,7 +12864,6 @@ class GitIgnoreManager {
|
|
|
12864
12864
|
// src/hooks/index.ts
|
|
12865
12865
|
class HookManager {
|
|
12866
12866
|
hooks = {};
|
|
12867
|
-
constructor() {}
|
|
12868
12867
|
register(name, hook) {
|
|
12869
12868
|
this.hooks[name] = hook;
|
|
12870
12869
|
}
|
|
@@ -12948,7 +12947,6 @@ class AIRulesCore {
|
|
|
12948
12947
|
return this.backupManager.listBackups();
|
|
12949
12948
|
}
|
|
12950
12949
|
async clean() {
|
|
12951
|
-
console.log("Clean functionality would be implemented here");
|
|
12952
12950
|
await this.gitIgnoreManager.cleanupGitIgnore();
|
|
12953
12951
|
}
|
|
12954
12952
|
async validate() {
|
|
@@ -12981,12 +12979,15 @@ class AIRulesCore {
|
|
|
12981
12979
|
if (!mcpGroups.has(outputPath)) {
|
|
12982
12980
|
mcpGroups.set(outputPath, []);
|
|
12983
12981
|
}
|
|
12984
|
-
mcpGroups.get(outputPath)
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
|
|
12988
|
-
|
|
12989
|
-
|
|
12982
|
+
const group = mcpGroups.get(outputPath);
|
|
12983
|
+
if (group) {
|
|
12984
|
+
group.push({
|
|
12985
|
+
name: mcp.name,
|
|
12986
|
+
config: mcp.config,
|
|
12987
|
+
agent,
|
|
12988
|
+
outputPath
|
|
12989
|
+
});
|
|
12990
|
+
}
|
|
12990
12991
|
}
|
|
12991
12992
|
}
|
|
12992
12993
|
for (const [outputPath, mcps] of mcpGroups) {
|
|
@@ -13070,10 +13071,10 @@ import { existsSync as existsSync6 } from "fs";
|
|
|
13070
13071
|
import { join as join4 } from "path";
|
|
13071
13072
|
class ConfigLoader {
|
|
13072
13073
|
static DEFAULT_CONFIG_PATHS = [
|
|
13073
|
-
"
|
|
13074
|
-
"
|
|
13075
|
-
"config/
|
|
13076
|
-
"config/
|
|
13074
|
+
"glooit.config.ts",
|
|
13075
|
+
"glooit.config.js",
|
|
13076
|
+
"config/glooit.ts",
|
|
13077
|
+
"config/glooit.js"
|
|
13077
13078
|
];
|
|
13078
13079
|
static async load(customPath) {
|
|
13079
13080
|
const configPath = customPath || this.findConfigFile();
|
|
@@ -13109,24 +13110,54 @@ class ConfigLoader {
|
|
|
13109
13110
|
}
|
|
13110
13111
|
}
|
|
13111
13112
|
static createInitialConfig() {
|
|
13112
|
-
return
|
|
13113
|
+
return this.createTypedConfig();
|
|
13114
|
+
}
|
|
13115
|
+
static createTypedConfig() {
|
|
13116
|
+
return `import type { Config } from 'glooit';
|
|
13113
13117
|
|
|
13114
13118
|
export default {
|
|
13115
|
-
configDir: '.
|
|
13119
|
+
configDir: '.glooit',
|
|
13120
|
+
targets: ['claude', 'cursor'],
|
|
13116
13121
|
|
|
13117
13122
|
rules: [
|
|
13118
13123
|
{
|
|
13119
|
-
|
|
13120
|
-
|
|
13124
|
+
name: 'main',
|
|
13125
|
+
file: '.glooit/main.md',
|
|
13121
13126
|
targets: ['claude', 'cursor']
|
|
13122
13127
|
}
|
|
13123
13128
|
],
|
|
13124
13129
|
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
|
|
13130
|
+
mcps: [
|
|
13131
|
+
// {
|
|
13132
|
+
// name: 'example-server',
|
|
13133
|
+
// file: '.glooit/mcp.json',
|
|
13134
|
+
// targets: ['claude']
|
|
13135
|
+
// }
|
|
13136
|
+
]
|
|
13129
13137
|
} satisfies Config;
|
|
13138
|
+
`;
|
|
13139
|
+
}
|
|
13140
|
+
static createPlainConfig() {
|
|
13141
|
+
return `export default {
|
|
13142
|
+
configDir: '.glooit',
|
|
13143
|
+
targets: ['claude', 'cursor'],
|
|
13144
|
+
|
|
13145
|
+
rules: [
|
|
13146
|
+
{
|
|
13147
|
+
name: 'main',
|
|
13148
|
+
file: '.glooit/main.md',
|
|
13149
|
+
targets: ['claude', 'cursor']
|
|
13150
|
+
}
|
|
13151
|
+
],
|
|
13152
|
+
|
|
13153
|
+
mcps: [
|
|
13154
|
+
// {
|
|
13155
|
+
// name: 'example-server',
|
|
13156
|
+
// file: '.glooit/mcp.json',
|
|
13157
|
+
// targets: ['claude']
|
|
13158
|
+
// }
|
|
13159
|
+
]
|
|
13160
|
+
};
|
|
13130
13161
|
`;
|
|
13131
13162
|
}
|
|
13132
13163
|
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const AgentSchema: z.ZodEnum<{
|
|
3
|
+
claude: "claude";
|
|
4
|
+
cursor: "cursor";
|
|
5
|
+
codex: "codex";
|
|
6
|
+
roocode: "roocode";
|
|
7
|
+
}>;
|
|
8
|
+
export type Agent = z.infer<typeof AgentSchema>;
|
|
9
|
+
export declare const HookFunctionSchema: z.ZodAny;
|
|
10
|
+
export declare const RuleSchema: z.ZodObject<{
|
|
11
|
+
file: z.ZodString;
|
|
12
|
+
to: z.ZodString;
|
|
13
|
+
globs: z.ZodOptional<z.ZodString>;
|
|
14
|
+
targets: z.ZodArray<z.ZodEnum<{
|
|
15
|
+
claude: "claude";
|
|
16
|
+
cursor: "cursor";
|
|
17
|
+
codex: "codex";
|
|
18
|
+
roocode: "roocode";
|
|
19
|
+
}>>;
|
|
20
|
+
hooks: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
export declare const CommandSchema: z.ZodObject<{
|
|
23
|
+
command: z.ZodString;
|
|
24
|
+
file: z.ZodString;
|
|
25
|
+
targets: z.ZodArray<z.ZodEnum<{
|
|
26
|
+
claude: "claude";
|
|
27
|
+
cursor: "cursor";
|
|
28
|
+
codex: "codex";
|
|
29
|
+
roocode: "roocode";
|
|
30
|
+
}>>;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
export declare const McpConfigSchema: z.ZodObject<{
|
|
33
|
+
command: z.ZodOptional<z.ZodString>;
|
|
34
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
35
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
36
|
+
type: z.ZodOptional<z.ZodString>;
|
|
37
|
+
url: z.ZodOptional<z.ZodString>;
|
|
38
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
39
|
+
alwaysAllow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
40
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export declare const McpSchema: z.ZodObject<{
|
|
43
|
+
name: z.ZodString;
|
|
44
|
+
config: z.ZodObject<{
|
|
45
|
+
command: z.ZodOptional<z.ZodString>;
|
|
46
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
47
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
48
|
+
type: z.ZodOptional<z.ZodString>;
|
|
49
|
+
url: z.ZodOptional<z.ZodString>;
|
|
50
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
51
|
+
alwaysAllow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
52
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
targets: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
55
|
+
claude: "claude";
|
|
56
|
+
cursor: "cursor";
|
|
57
|
+
codex: "codex";
|
|
58
|
+
roocode: "roocode";
|
|
59
|
+
}>>>;
|
|
60
|
+
outputPath: z.ZodOptional<z.ZodString>;
|
|
61
|
+
}, z.core.$strip>;
|
|
62
|
+
export declare const BackupConfigSchema: z.ZodObject<{
|
|
63
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
64
|
+
retention: z.ZodDefault<z.ZodNumber>;
|
|
65
|
+
}, z.core.$strip>;
|
|
66
|
+
export declare const HooksSchema: z.ZodObject<{
|
|
67
|
+
before: z.ZodOptional<z.ZodArray<z.ZodAny>>;
|
|
68
|
+
after: z.ZodOptional<z.ZodArray<z.ZodAny>>;
|
|
69
|
+
error: z.ZodOptional<z.ZodArray<z.ZodAny>>;
|
|
70
|
+
}, z.core.$strip>;
|
|
71
|
+
export declare const ConfigSchema: z.ZodObject<{
|
|
72
|
+
configDir: z.ZodDefault<z.ZodString>;
|
|
73
|
+
rules: z.ZodArray<z.ZodObject<{
|
|
74
|
+
file: z.ZodString;
|
|
75
|
+
to: z.ZodString;
|
|
76
|
+
globs: z.ZodOptional<z.ZodString>;
|
|
77
|
+
targets: z.ZodArray<z.ZodEnum<{
|
|
78
|
+
claude: "claude";
|
|
79
|
+
cursor: "cursor";
|
|
80
|
+
codex: "codex";
|
|
81
|
+
roocode: "roocode";
|
|
82
|
+
}>>;
|
|
83
|
+
hooks: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
84
|
+
}, z.core.$strip>>;
|
|
85
|
+
commands: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
86
|
+
command: z.ZodString;
|
|
87
|
+
file: z.ZodString;
|
|
88
|
+
targets: z.ZodArray<z.ZodEnum<{
|
|
89
|
+
claude: "claude";
|
|
90
|
+
cursor: "cursor";
|
|
91
|
+
codex: "codex";
|
|
92
|
+
roocode: "roocode";
|
|
93
|
+
}>>;
|
|
94
|
+
}, z.core.$strip>>>;
|
|
95
|
+
mcps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
96
|
+
name: z.ZodString;
|
|
97
|
+
config: z.ZodObject<{
|
|
98
|
+
command: z.ZodOptional<z.ZodString>;
|
|
99
|
+
args: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
100
|
+
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
101
|
+
type: z.ZodOptional<z.ZodString>;
|
|
102
|
+
url: z.ZodOptional<z.ZodString>;
|
|
103
|
+
headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
104
|
+
alwaysAllow: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
105
|
+
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
106
|
+
}, z.core.$strip>;
|
|
107
|
+
targets: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
108
|
+
claude: "claude";
|
|
109
|
+
cursor: "cursor";
|
|
110
|
+
codex: "codex";
|
|
111
|
+
roocode: "roocode";
|
|
112
|
+
}>>>;
|
|
113
|
+
outputPath: z.ZodOptional<z.ZodString>;
|
|
114
|
+
}, z.core.$strip>>>;
|
|
115
|
+
mergeMcps: z.ZodDefault<z.ZodBoolean>;
|
|
116
|
+
hooks: z.ZodOptional<z.ZodObject<{
|
|
117
|
+
before: z.ZodOptional<z.ZodArray<z.ZodAny>>;
|
|
118
|
+
after: z.ZodOptional<z.ZodArray<z.ZodAny>>;
|
|
119
|
+
error: z.ZodOptional<z.ZodArray<z.ZodAny>>;
|
|
120
|
+
}, z.core.$strip>>;
|
|
121
|
+
backup: z.ZodOptional<z.ZodObject<{
|
|
122
|
+
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
123
|
+
retention: z.ZodDefault<z.ZodNumber>;
|
|
124
|
+
}, z.core.$strip>>;
|
|
125
|
+
}, z.core.$strip>;
|
|
126
|
+
export type Rule = z.infer<typeof RuleSchema>;
|
|
127
|
+
export type Command = z.infer<typeof CommandSchema>;
|
|
128
|
+
export type McpConfig = z.infer<typeof McpConfigSchema>;
|
|
129
|
+
export type Mcp = z.infer<typeof McpSchema>;
|
|
130
|
+
export interface ResolvedMcp extends Omit<Mcp, 'outputPath'> {
|
|
131
|
+
outputPath: string;
|
|
132
|
+
}
|
|
133
|
+
export type BackupConfig = z.infer<typeof BackupConfigSchema>;
|
|
134
|
+
export type Hooks = z.infer<typeof HooksSchema>;
|
|
135
|
+
export type Config = z.infer<typeof ConfigSchema>;
|
|
136
|
+
export interface AgentMapping {
|
|
137
|
+
path: string;
|
|
138
|
+
format: 'markdown' | 'frontmatter';
|
|
139
|
+
directory?: string;
|
|
140
|
+
mcpPath: string;
|
|
141
|
+
}
|
|
142
|
+
export interface SyncContext {
|
|
143
|
+
config: Config;
|
|
144
|
+
rule: Rule;
|
|
145
|
+
content: string;
|
|
146
|
+
targetPath: string;
|
|
147
|
+
agent: Agent;
|
|
148
|
+
}
|
|
149
|
+
export interface BackupEntry {
|
|
150
|
+
timestamp: string;
|
|
151
|
+
files: {
|
|
152
|
+
path: string;
|
|
153
|
+
content: string;
|
|
154
|
+
}[];
|
|
155
|
+
}
|
|
156
|
+
export declare function defineRules(config: Config): Config;
|
package/package.json
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "glooit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "🧴 Sync your AI agent configurations and rules across platforms with ease",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
7
8
|
"type": "module",
|
|
8
9
|
"bin": {
|
|
9
|
-
"
|
|
10
|
+
"glooit": "dist/cli/index.js"
|
|
10
11
|
},
|
|
11
12
|
"scripts": {
|
|
12
|
-
"build": "bun run typecheck && bun run lint && bun build src/index.ts --outdir dist --target node",
|
|
13
|
+
"build": "bun run typecheck && bun run lint && bun build src/index.ts --outdir dist --target node && tsc --project tsconfig.build.json",
|
|
13
14
|
"build:cli": "bun build src/cli/index.ts --outdir dist/cli --target node",
|
|
14
|
-
"build:binary": "bun build src/cli/index.ts --compile --outfile bin/
|
|
15
|
-
"build:binary:linux": "bun build src/cli/index.ts --compile --target=bun-linux-x64 --outfile bin/
|
|
16
|
-
"build:binary:macos": "bun build src/cli/index.ts --compile --target=bun-darwin-arm64 --outfile bin/
|
|
17
|
-
"build:binary:windows": "bun build src/cli/index.ts --compile --target=bun-windows-x64 --outfile bin/
|
|
15
|
+
"build:binary": "bun build src/cli/index.ts --compile --outfile bin/glooit",
|
|
16
|
+
"build:binary:linux": "bun build src/cli/index.ts --compile --target=bun-linux-x64 --outfile bin/glooit-linux",
|
|
17
|
+
"build:binary:macos": "bun build src/cli/index.ts --compile --target=bun-darwin-arm64 --outfile bin/glooit-macos",
|
|
18
|
+
"build:binary:windows": "bun build src/cli/index.ts --compile --target=bun-windows-x64 --outfile bin/glooit-windows.exe",
|
|
18
19
|
"dev": "bun run src/cli/index.ts",
|
|
19
20
|
"test": "vitest",
|
|
20
|
-
"test:ui": "vitest --ui",
|
|
21
21
|
"test:run": "vitest run",
|
|
22
22
|
"test:coverage": "vitest run --coverage",
|
|
23
23
|
"typecheck": "tsc --noEmit",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"lint:fix": "oxlint src tests --fix",
|
|
26
26
|
"format": "oxlint src tests --fix",
|
|
27
27
|
"check": "bun run typecheck && bun run lint && bun run test:run",
|
|
28
|
-
"
|
|
28
|
+
"taze": "bunx taze",
|
|
29
29
|
"prepublishOnly": "bun run check && bun run build && bun run build:cli",
|
|
30
|
-
"install:local": "bun run build:binary && sudo mv bin/
|
|
30
|
+
"install:local": "bun run build:binary && sudo mv bin/glooit /usr/local/bin/"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|
|
@@ -52,25 +52,26 @@
|
|
|
52
52
|
"license": "MIT",
|
|
53
53
|
"repository": {
|
|
54
54
|
"type": "git",
|
|
55
|
-
"url": "https://github.com/nikuscs/
|
|
55
|
+
"url": "https://github.com/nikuscs/glooit.git"
|
|
56
56
|
},
|
|
57
57
|
"bugs": {
|
|
58
|
-
"url": "https://github.com/nikuscs/
|
|
58
|
+
"url": "https://github.com/nikuscs/glooit/issues"
|
|
59
59
|
},
|
|
60
|
-
"homepage": "https://github.com/nikuscs/
|
|
60
|
+
"homepage": "https://github.com/nikuscs/glooit#readme",
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/bun": "latest",
|
|
63
63
|
"@types/node": "^24.5.2",
|
|
64
64
|
"@vitest/ui": "^3.2.4",
|
|
65
|
+
"bumpp": "^10.2.3",
|
|
65
66
|
"oxlint": "^1.17.0",
|
|
66
|
-
"vitest": "^3.2.4"
|
|
67
|
-
"bumpp": "^9.2.0"
|
|
67
|
+
"vitest": "^3.2.4"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"typescript": "^5"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"commander": "^14.0.1",
|
|
74
|
+
"package-manager-detector": "^1.3.0",
|
|
74
75
|
"zod": "^4.1.11"
|
|
75
76
|
}
|
|
76
|
-
}
|
|
77
|
+
}
|