binder-cli 1.1.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/LICENSE +21 -0
- package/README.md +177 -0
- package/bin/binder.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +119 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/context.d.ts +12 -0
- package/dist/commands/context.d.ts.map +1 -0
- package/dist/commands/context.js +105 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +119 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/pull.d.ts +5 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +47 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +116 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/core/config/parser.d.ts +24 -0
- package/dist/core/config/parser.d.ts.map +1 -0
- package/dist/core/config/parser.js +116 -0
- package/dist/core/config/parser.js.map +1 -0
- package/dist/core/config/types.d.ts +142 -0
- package/dist/core/config/types.d.ts.map +1 -0
- package/dist/core/config/types.js +71 -0
- package/dist/core/config/types.js.map +1 -0
- package/dist/core/generator/context-map.d.ts +6 -0
- package/dist/core/generator/context-map.d.ts.map +1 -0
- package/dist/core/generator/context-map.js +124 -0
- package/dist/core/generator/context-map.js.map +1 -0
- package/dist/core/generator/injection-content.d.ts +9 -0
- package/dist/core/generator/injection-content.d.ts.map +1 -0
- package/dist/core/generator/injection-content.js +38 -0
- package/dist/core/generator/injection-content.js.map +1 -0
- package/dist/core/generator/rule-injector.d.ts +33 -0
- package/dist/core/generator/rule-injector.d.ts.map +1 -0
- package/dist/core/generator/rule-injector.js +208 -0
- package/dist/core/generator/rule-injector.js.map +1 -0
- package/dist/core/git/operations.d.ts +52 -0
- package/dist/core/git/operations.d.ts.map +1 -0
- package/dist/core/git/operations.js +221 -0
- package/dist/core/git/operations.js.map +1 -0
- package/dist/core/workspace/orchestrator.d.ts +28 -0
- package/dist/core/workspace/orchestrator.d.ts.map +1 -0
- package/dist/core/workspace/orchestrator.js +151 -0
- package/dist/core/workspace/orchestrator.js.map +1 -0
- package/dist/core/workspace/status.d.ts +45 -0
- package/dist/core/workspace/status.d.ts.map +1 -0
- package/dist/core/workspace/status.js +142 -0
- package/dist/core/workspace/status.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/errors.d.ts +45 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +83 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/filesystem.d.ts +42 -0
- package/dist/utils/filesystem.d.ts.map +1 -0
- package/dist/utils/filesystem.js +152 -0
- package/dist/utils/filesystem.js.map +1 -0
- package/dist/utils/logger.d.ts +59 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +118 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +79 -0
- package/templates/binder.yaml.template +52 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Content templates for AI rule file injection
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getInjectionContent = getInjectionContent;
|
|
7
|
+
/**
|
|
8
|
+
* Generate the injected content for rule files
|
|
9
|
+
*/
|
|
10
|
+
function getInjectionContent(format, contextMapPath) {
|
|
11
|
+
if (format === 'markdown') {
|
|
12
|
+
return getMarkdownContent(contextMapPath);
|
|
13
|
+
}
|
|
14
|
+
// Default to markdown
|
|
15
|
+
return getMarkdownContent(contextMapPath);
|
|
16
|
+
}
|
|
17
|
+
function getMarkdownContent(contextMapPath) {
|
|
18
|
+
return `## Binder Workspace Instructions
|
|
19
|
+
|
|
20
|
+
This is a multi-repository workspace managed by [Binder](https://github.com/corrjo/binder).
|
|
21
|
+
|
|
22
|
+
**IMPORTANT**: Before making changes, read \`${contextMapPath}\` to understand your permissions.
|
|
23
|
+
|
|
24
|
+
### Scope System
|
|
25
|
+
|
|
26
|
+
Repositories in this workspace have one of three scopes:
|
|
27
|
+
|
|
28
|
+
- **OWNER** (Full Authority): You have complete control. Refactor, restructure, and improve freely.
|
|
29
|
+
- **PLATFORM** (Restricted): Read fully, but make only minimal, well-justified changes.
|
|
30
|
+
- **REFERENCE** (Read-Only): Use for context only. Do not modify these repositories.
|
|
31
|
+
|
|
32
|
+
### Required Action
|
|
33
|
+
|
|
34
|
+
1. Read \`${contextMapPath}\` at the start of each session
|
|
35
|
+
2. Check the scope of any repository before making changes
|
|
36
|
+
3. Respect the boundaries defined for each repository`;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=injection-content.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"injection-content.js","sourceRoot":"","sources":["../../../src/core/generator/injection-content.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAOH,kDAMC;AATD;;GAEG;AACH,SAAgB,mBAAmB,CAAC,MAAuB,EAAE,cAAsB;IACjF,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,OAAO,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAC5C,CAAC;IACD,sBAAsB;IACtB,OAAO,kBAAkB,CAAC,cAAc,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,kBAAkB,CAAC,cAAsB;IAChD,OAAO;;;;+CAIsC,cAAc;;;;;;;;;;;;YAYjD,cAAc;;sDAE4B,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule file injection for AI tool configurations
|
|
3
|
+
*/
|
|
4
|
+
export interface InjectionTargets {
|
|
5
|
+
claude?: boolean;
|
|
6
|
+
cursor?: boolean;
|
|
7
|
+
roo?: boolean;
|
|
8
|
+
agents?: boolean;
|
|
9
|
+
file?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface InjectionOptions {
|
|
12
|
+
basePath: string;
|
|
13
|
+
contextMapPath: string;
|
|
14
|
+
targets: InjectionTargets;
|
|
15
|
+
}
|
|
16
|
+
export interface InjectionResult {
|
|
17
|
+
file: string;
|
|
18
|
+
action: 'updated' | 'unchanged' | 'skipped' | 'error';
|
|
19
|
+
message?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Inject content between markers, handling idempotency
|
|
23
|
+
* Exported for testing
|
|
24
|
+
*/
|
|
25
|
+
export declare function injectContent(existingContent: string, injectedContent: string): {
|
|
26
|
+
content: string;
|
|
27
|
+
wasUpdated: boolean;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Main entry point: inject into all specified rule files
|
|
31
|
+
*/
|
|
32
|
+
export declare function injectIntoRuleFiles(options: InjectionOptions): Promise<InjectionResult[]>;
|
|
33
|
+
//# sourceMappingURL=rule-injector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-injector.d.ts","sourceRoot":"","sources":["../../../src/core/generator/rule-injector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkDH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,GACtB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAsB1C;AAgGD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAoC/F"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rule file injection for AI tool configurations
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.injectContent = injectContent;
|
|
40
|
+
exports.injectIntoRuleFiles = injectIntoRuleFiles;
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const filesystem_1 = require("../../utils/filesystem");
|
|
43
|
+
const logger_1 = require("../../utils/logger");
|
|
44
|
+
const injection_content_1 = require("./injection-content");
|
|
45
|
+
// Marker constants for idempotent injection
|
|
46
|
+
const MARKER_START = '<!-- binder:start -->';
|
|
47
|
+
const MARKER_END = '<!-- binder:end -->';
|
|
48
|
+
/**
|
|
49
|
+
* Known AI tool targets
|
|
50
|
+
*/
|
|
51
|
+
const TARGETS = {
|
|
52
|
+
claude: {
|
|
53
|
+
filename: 'CLAUDE.md',
|
|
54
|
+
format: 'markdown',
|
|
55
|
+
createHint: "Run 'claude /init' or create CLAUDE.md manually",
|
|
56
|
+
},
|
|
57
|
+
cursor: {
|
|
58
|
+
filename: '.cursorrules',
|
|
59
|
+
format: 'markdown',
|
|
60
|
+
createHint: 'Create .cursorrules in your project root',
|
|
61
|
+
},
|
|
62
|
+
roo: {
|
|
63
|
+
filename: 'rules.md',
|
|
64
|
+
directory: '.roo',
|
|
65
|
+
format: 'markdown',
|
|
66
|
+
createHint: "Run 'roo init' or create .roo/rules.md manually",
|
|
67
|
+
},
|
|
68
|
+
agents: {
|
|
69
|
+
filename: 'agents.md',
|
|
70
|
+
format: 'markdown',
|
|
71
|
+
createHint: 'Create agents.md in your project root',
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Inject content between markers, handling idempotency
|
|
76
|
+
* Exported for testing
|
|
77
|
+
*/
|
|
78
|
+
function injectContent(existingContent, injectedContent) {
|
|
79
|
+
const markerStartIndex = existingContent.indexOf(MARKER_START);
|
|
80
|
+
const markerEndIndex = existingContent.indexOf(MARKER_END);
|
|
81
|
+
const wrappedContent = `${MARKER_START}\n${injectedContent}\n${MARKER_END}`;
|
|
82
|
+
// Both markers exist and are in correct order
|
|
83
|
+
if (markerStartIndex !== -1 && markerEndIndex !== -1 && markerEndIndex > markerStartIndex) {
|
|
84
|
+
const before = existingContent.substring(0, markerStartIndex);
|
|
85
|
+
const after = existingContent.substring(markerEndIndex + MARKER_END.length);
|
|
86
|
+
const newContent = before + wrappedContent + after;
|
|
87
|
+
const wasUpdated = newContent !== existingContent;
|
|
88
|
+
return { content: newContent, wasUpdated };
|
|
89
|
+
}
|
|
90
|
+
// No markers or malformed - append to end
|
|
91
|
+
const needsNewline = existingContent.length > 0 && !existingContent.endsWith('\n');
|
|
92
|
+
const separator = existingContent.length === 0 ? '' : needsNewline ? '\n\n' : '\n';
|
|
93
|
+
return {
|
|
94
|
+
content: existingContent + separator + wrappedContent + '\n',
|
|
95
|
+
wasUpdated: true,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Inject into a single known target file
|
|
100
|
+
*/
|
|
101
|
+
async function injectIntoKnownTarget(targetKey, basePath, contextMapPath) {
|
|
102
|
+
const config = TARGETS[targetKey];
|
|
103
|
+
const dir = config.directory ? path.join(basePath, config.directory) : basePath;
|
|
104
|
+
const filePath = path.join(dir, config.filename);
|
|
105
|
+
const displayPath = config.directory ? `${config.directory}/${config.filename}` : config.filename;
|
|
106
|
+
// Check if file exists
|
|
107
|
+
if (!(await (0, filesystem_1.exists)(filePath))) {
|
|
108
|
+
return {
|
|
109
|
+
file: displayPath,
|
|
110
|
+
action: 'skipped',
|
|
111
|
+
message: config.createHint,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return injectIntoFilePath(filePath, displayPath, contextMapPath);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Inject into a custom file path
|
|
118
|
+
*/
|
|
119
|
+
async function injectIntoCustomFile(customPath, basePath, contextMapPath) {
|
|
120
|
+
const filePath = path.isAbsolute(customPath) ? customPath : path.join(basePath, customPath);
|
|
121
|
+
// Check if file exists
|
|
122
|
+
if (!(await (0, filesystem_1.exists)(filePath))) {
|
|
123
|
+
return {
|
|
124
|
+
file: customPath,
|
|
125
|
+
action: 'skipped',
|
|
126
|
+
message: `File not found: ${customPath}`,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return injectIntoFilePath(filePath, customPath, contextMapPath);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Core injection logic for a file path
|
|
133
|
+
*/
|
|
134
|
+
async function injectIntoFilePath(filePath, displayPath, contextMapPath) {
|
|
135
|
+
try {
|
|
136
|
+
const existingContent = await (0, filesystem_1.readFile)(filePath);
|
|
137
|
+
const injectedContent = (0, injection_content_1.getInjectionContent)('markdown', contextMapPath);
|
|
138
|
+
const { content, wasUpdated } = injectContent(existingContent, injectedContent);
|
|
139
|
+
if (wasUpdated) {
|
|
140
|
+
// Ensure parent directory exists (for .roo/rules.md case)
|
|
141
|
+
await (0, filesystem_1.ensureDir)(path.dirname(filePath));
|
|
142
|
+
await (0, filesystem_1.writeFile)(filePath, content);
|
|
143
|
+
return { file: displayPath, action: 'updated' };
|
|
144
|
+
}
|
|
145
|
+
return { file: displayPath, action: 'unchanged' };
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
const message = err instanceof Error ? err.message : 'Unknown error';
|
|
149
|
+
return { file: displayPath, action: 'error', message };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Log the result of an injection
|
|
154
|
+
*/
|
|
155
|
+
function logResult(result) {
|
|
156
|
+
switch (result.action) {
|
|
157
|
+
case 'updated':
|
|
158
|
+
(0, logger_1.success)(`Updated Binder instructions in ${result.file}`);
|
|
159
|
+
break;
|
|
160
|
+
case 'unchanged':
|
|
161
|
+
(0, logger_1.info)(`${result.file} already up to date`);
|
|
162
|
+
break;
|
|
163
|
+
case 'skipped':
|
|
164
|
+
(0, logger_1.warning)(`${result.file} not found. ${result.message}`);
|
|
165
|
+
break;
|
|
166
|
+
case 'error':
|
|
167
|
+
(0, logger_1.warning)(`Failed to update ${result.file}: ${result.message}`);
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Main entry point: inject into all specified rule files
|
|
173
|
+
*/
|
|
174
|
+
async function injectIntoRuleFiles(options) {
|
|
175
|
+
const results = [];
|
|
176
|
+
const { basePath, contextMapPath, targets } = options;
|
|
177
|
+
// Process known targets
|
|
178
|
+
if (targets.claude) {
|
|
179
|
+
const result = await injectIntoKnownTarget('claude', basePath, contextMapPath);
|
|
180
|
+
results.push(result);
|
|
181
|
+
logResult(result);
|
|
182
|
+
}
|
|
183
|
+
if (targets.cursor) {
|
|
184
|
+
const result = await injectIntoKnownTarget('cursor', basePath, contextMapPath);
|
|
185
|
+
results.push(result);
|
|
186
|
+
logResult(result);
|
|
187
|
+
}
|
|
188
|
+
if (targets.roo) {
|
|
189
|
+
const result = await injectIntoKnownTarget('roo', basePath, contextMapPath);
|
|
190
|
+
results.push(result);
|
|
191
|
+
logResult(result);
|
|
192
|
+
}
|
|
193
|
+
if (targets.agents) {
|
|
194
|
+
const result = await injectIntoKnownTarget('agents', basePath, contextMapPath);
|
|
195
|
+
results.push(result);
|
|
196
|
+
logResult(result);
|
|
197
|
+
}
|
|
198
|
+
// Process custom files
|
|
199
|
+
if (targets.file && targets.file.length > 0) {
|
|
200
|
+
for (const customPath of targets.file) {
|
|
201
|
+
const result = await injectIntoCustomFile(customPath, basePath, contextMapPath);
|
|
202
|
+
results.push(result);
|
|
203
|
+
logResult(result);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return results;
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=rule-injector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-injector.js","sourceRoot":"","sources":["../../../src/core/generator/rule-injector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repository status information
|
|
3
|
+
*/
|
|
4
|
+
export interface RepoStatus {
|
|
5
|
+
exists: boolean;
|
|
6
|
+
isDirty: boolean;
|
|
7
|
+
currentBranch: string | null;
|
|
8
|
+
hasUntracked: boolean;
|
|
9
|
+
hasModified: boolean;
|
|
10
|
+
hasStaged: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Clone options
|
|
14
|
+
*/
|
|
15
|
+
export interface CloneOptions {
|
|
16
|
+
depth?: number;
|
|
17
|
+
branch?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Check if a path is a git repository
|
|
21
|
+
*/
|
|
22
|
+
export declare function isGitRepo(repoPath: string): Promise<boolean>;
|
|
23
|
+
/**
|
|
24
|
+
* Get the status of a git repository
|
|
25
|
+
*/
|
|
26
|
+
export declare function getRepoStatus(repoPath: string): Promise<RepoStatus>;
|
|
27
|
+
/**
|
|
28
|
+
* Get the current branch name of a repository
|
|
29
|
+
*/
|
|
30
|
+
export declare function getCurrentBranch(repoPath: string): Promise<string | null>;
|
|
31
|
+
/**
|
|
32
|
+
* Checkout a branch in a repository
|
|
33
|
+
* Throws DirtyRepositoryError if repo has uncommitted changes
|
|
34
|
+
*/
|
|
35
|
+
export declare function checkoutBranch(repoPath: string, branchName: string, repoName?: string): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Clone a repository to a destination path
|
|
38
|
+
*/
|
|
39
|
+
export declare function cloneRepository(url: string, destPath: string, options?: CloneOptions): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Fetch updates from remote
|
|
42
|
+
*/
|
|
43
|
+
export declare function fetchRemote(repoPath: string): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Pull updates from remote
|
|
46
|
+
*/
|
|
47
|
+
export declare function pullUpdates(repoPath: string, repoName?: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Check if a branch exists (locally or remotely)
|
|
50
|
+
*/
|
|
51
|
+
export declare function branchExists(repoPath: string, branchName: string): Promise<boolean>;
|
|
52
|
+
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../../../src/core/git/operations.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQlE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0CzE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAQ/E;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASjE;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBpF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYzF"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.isGitRepo = isGitRepo;
|
|
40
|
+
exports.getRepoStatus = getRepoStatus;
|
|
41
|
+
exports.getCurrentBranch = getCurrentBranch;
|
|
42
|
+
exports.checkoutBranch = checkoutBranch;
|
|
43
|
+
exports.cloneRepository = cloneRepository;
|
|
44
|
+
exports.fetchRemote = fetchRemote;
|
|
45
|
+
exports.pullUpdates = pullUpdates;
|
|
46
|
+
exports.branchExists = branchExists;
|
|
47
|
+
const simple_git_1 = __importDefault(require("simple-git"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const fs = __importStar(require("fs-extra"));
|
|
50
|
+
const errors_1 = require("../../utils/errors");
|
|
51
|
+
const logger_1 = require("../../utils/logger");
|
|
52
|
+
/**
|
|
53
|
+
* Check if a path is a git repository
|
|
54
|
+
*/
|
|
55
|
+
async function isGitRepo(repoPath) {
|
|
56
|
+
const gitDir = path.join(repoPath, '.git');
|
|
57
|
+
try {
|
|
58
|
+
const stat = await fs.stat(gitDir);
|
|
59
|
+
return stat.isDirectory();
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Get the status of a git repository
|
|
67
|
+
*/
|
|
68
|
+
async function getRepoStatus(repoPath) {
|
|
69
|
+
const exists = await isGitRepo(repoPath);
|
|
70
|
+
if (!exists) {
|
|
71
|
+
return {
|
|
72
|
+
exists: false,
|
|
73
|
+
isDirty: false,
|
|
74
|
+
currentBranch: null,
|
|
75
|
+
hasUntracked: false,
|
|
76
|
+
hasModified: false,
|
|
77
|
+
hasStaged: false,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
81
|
+
try {
|
|
82
|
+
const status = await git.status();
|
|
83
|
+
const hasUntracked = status.not_added.length > 0;
|
|
84
|
+
const hasModified = status.modified.length > 0 || status.deleted.length > 0;
|
|
85
|
+
const hasStaged = status.staged.length > 0 || status.created.length > 0 || status.renamed.length > 0;
|
|
86
|
+
return {
|
|
87
|
+
exists: true,
|
|
88
|
+
isDirty: hasUntracked || hasModified || hasStaged,
|
|
89
|
+
currentBranch: status.current || null,
|
|
90
|
+
hasUntracked,
|
|
91
|
+
hasModified,
|
|
92
|
+
hasStaged,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
97
|
+
(0, logger_1.debug)(`Error getting status for ${repoPath}: ${message}`);
|
|
98
|
+
return {
|
|
99
|
+
exists: true,
|
|
100
|
+
isDirty: false,
|
|
101
|
+
currentBranch: null,
|
|
102
|
+
hasUntracked: false,
|
|
103
|
+
hasModified: false,
|
|
104
|
+
hasStaged: false,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Get the current branch name of a repository
|
|
110
|
+
*/
|
|
111
|
+
async function getCurrentBranch(repoPath) {
|
|
112
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
113
|
+
try {
|
|
114
|
+
const status = await git.status();
|
|
115
|
+
return status.current || null;
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Checkout a branch in a repository
|
|
123
|
+
* Throws DirtyRepositoryError if repo has uncommitted changes
|
|
124
|
+
*/
|
|
125
|
+
async function checkoutBranch(repoPath, branchName, repoName) {
|
|
126
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
127
|
+
// Check current branch first
|
|
128
|
+
const currentBranch = await getCurrentBranch(repoPath);
|
|
129
|
+
if (currentBranch === branchName) {
|
|
130
|
+
(0, logger_1.debug)(`Already on branch ${branchName}`);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Check if repo is dirty
|
|
134
|
+
const status = await getRepoStatus(repoPath);
|
|
135
|
+
if (status.isDirty) {
|
|
136
|
+
throw new errors_1.DirtyRepositoryError(repoName || path.basename(repoPath));
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
// Try to checkout the branch
|
|
140
|
+
await git.checkout(branchName);
|
|
141
|
+
(0, logger_1.debug)(`Checked out branch ${branchName}`);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
145
|
+
throw new errors_1.GitError(`Failed to checkout branch ${branchName}: ${message}`, repoName);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Clone a repository to a destination path
|
|
150
|
+
*/
|
|
151
|
+
async function cloneRepository(url, destPath, options) {
|
|
152
|
+
const git = (0, simple_git_1.default)({
|
|
153
|
+
baseDir: process.cwd(),
|
|
154
|
+
binary: 'git',
|
|
155
|
+
maxConcurrentProcesses: 6,
|
|
156
|
+
});
|
|
157
|
+
const cloneArgs = [];
|
|
158
|
+
if (options?.depth) {
|
|
159
|
+
cloneArgs.push('--depth', options.depth.toString());
|
|
160
|
+
}
|
|
161
|
+
if (options?.branch) {
|
|
162
|
+
cloneArgs.push('--branch', options.branch);
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
(0, logger_1.debug)(`Cloning ${url} to ${destPath}`);
|
|
166
|
+
await git.clone(url, destPath, cloneArgs);
|
|
167
|
+
(0, logger_1.debug)(`Successfully cloned ${url}`);
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
171
|
+
throw new errors_1.CloneError(url, message);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Fetch updates from remote
|
|
176
|
+
*/
|
|
177
|
+
async function fetchRemote(repoPath) {
|
|
178
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
179
|
+
try {
|
|
180
|
+
await git.fetch();
|
|
181
|
+
(0, logger_1.debug)(`Fetched updates for ${repoPath}`);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
185
|
+
throw new errors_1.GitError(`Failed to fetch: ${message}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Pull updates from remote
|
|
190
|
+
*/
|
|
191
|
+
async function pullUpdates(repoPath, repoName) {
|
|
192
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
193
|
+
// Check if repo is dirty first
|
|
194
|
+
const status = await getRepoStatus(repoPath);
|
|
195
|
+
if (status.isDirty) {
|
|
196
|
+
throw new errors_1.DirtyRepositoryError(repoName || path.basename(repoPath));
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
await git.pull();
|
|
200
|
+
(0, logger_1.debug)(`Pulled updates for ${repoPath}`);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
204
|
+
throw new errors_1.GitError(`Failed to pull: ${message}`, repoName);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Check if a branch exists (locally or remotely)
|
|
209
|
+
*/
|
|
210
|
+
async function branchExists(repoPath, branchName) {
|
|
211
|
+
const git = (0, simple_git_1.default)(repoPath);
|
|
212
|
+
try {
|
|
213
|
+
const branches = await git.branch(['-a']);
|
|
214
|
+
const allBranches = [...branches.all];
|
|
215
|
+
return allBranches.some((b) => b === branchName || b === `remotes/origin/${branchName}` || b === `origin/${branchName}`);
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../../../src/core/git/operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BinderConfig } from '../config/types';
|
|
2
|
+
/**
|
|
3
|
+
* Result of orchestrating a single repository
|
|
4
|
+
*/
|
|
5
|
+
export interface RepoOrchestrationResult {
|
|
6
|
+
name: string;
|
|
7
|
+
path: string;
|
|
8
|
+
action: 'cloned' | 'checkout' | 'skipped' | 'up-to-date' | 'error';
|
|
9
|
+
branch?: string;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Result of orchestrating all repositories
|
|
14
|
+
*/
|
|
15
|
+
export interface OrchestrationResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
repos: RepoOrchestrationResult[];
|
|
18
|
+
cloned: number;
|
|
19
|
+
checkedOut: number;
|
|
20
|
+
skipped: number;
|
|
21
|
+
errors: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Orchestrate all repositories according to the configuration
|
|
25
|
+
* This is the main entry point for the `binder pull` command
|
|
26
|
+
*/
|
|
27
|
+
export declare function orchestrate(config: BinderConfig, basePath?: string): Promise<OrchestrationResult>;
|
|
28
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/core/workspace/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,iBAAiB,CAAC;AAMhE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,CAAC;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,uBAAuB,EAAE,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAyGD;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,YAAY,EACpB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,mBAAmB,CAAC,CA4D9B"}
|