@iloom/cli 0.6.0 → 0.6.1
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 +25 -0
- package/dist/{PRManager-OCSB2HPT.js → PRManager-GB3FOJ2W.js} +2 -2
- package/dist/README.md +25 -0
- package/dist/{chunk-WIJWIKAN.js → chunk-2A7WQKBE.js} +10 -2
- package/dist/{chunk-WIJWIKAN.js.map → chunk-2A7WQKBE.js.map} +1 -1
- package/dist/{chunk-PMVWQBWS.js → chunk-I75JMBNB.js} +2 -4
- package/dist/chunk-I75JMBNB.js.map +1 -0
- package/dist/{chunk-UB4TFAXJ.js → chunk-LVBRMTE6.js} +4 -50
- package/dist/chunk-LVBRMTE6.js.map +1 -0
- package/dist/{chunk-5IWU3HXE.js → chunk-VDA5JMB4.js} +3 -4
- package/dist/{chunk-5IWU3HXE.js.map → chunk-VDA5JMB4.js.map} +1 -1
- package/dist/{cleanup-OU2HFOOG.js → cleanup-BRUAINKE.js} +2 -2
- package/dist/cli.js +179 -14
- package/dist/cli.js.map +1 -1
- package/dist/{contribute-T7ENST5N.js → contribute-Q6GX6AXK.js} +95 -27
- package/dist/contribute-Q6GX6AXK.js.map +1 -0
- package/dist/{init-HB34Q5FH.js → init-UTYRHNJJ.js} +2 -2
- package/dist/prompts/init-prompt.txt +1 -8
- package/dist/{rebase-5EY3Q6XP.js → rebase-Y4AS6LQW.js} +2 -2
- package/package.json +1 -1
- package/dist/chunk-PMVWQBWS.js.map +0 -1
- package/dist/chunk-UB4TFAXJ.js.map +0 -1
- package/dist/contribute-T7ENST5N.js.map +0 -1
- /package/dist/{PRManager-OCSB2HPT.js.map → PRManager-GB3FOJ2W.js.map} +0 -0
- /package/dist/{cleanup-OU2HFOOG.js.map → cleanup-BRUAINKE.js.map} +0 -0
- /package/dist/{init-HB34Q5FH.js.map → init-UTYRHNJJ.js.map} +0 -0
- /package/dist/{rebase-5EY3Q6XP.js.map → rebase-Y4AS6LQW.js.map} +0 -0
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
FirstRunManager
|
|
4
|
+
} from "./chunk-Q7POFB5Q.js";
|
|
2
5
|
import {
|
|
3
6
|
executeGitCommand
|
|
4
7
|
} from "./chunk-GEXP5IOF.js";
|
|
@@ -21,8 +24,7 @@ import { existsSync, accessSync, constants } from "fs";
|
|
|
21
24
|
import { writeFile, mkdir } from "fs/promises";
|
|
22
25
|
import path from "path";
|
|
23
26
|
import chalk from "chalk";
|
|
24
|
-
var
|
|
25
|
-
var UPSTREAM_URL = "https://github.com/iloom-ai/iloom-cli.git";
|
|
27
|
+
var DEFAULT_REPO = "iloom-ai/iloom-cli";
|
|
26
28
|
var MAX_PATH_LENGTH = 255;
|
|
27
29
|
var RESERVED_NAMES = [
|
|
28
30
|
"CON",
|
|
@@ -69,6 +71,35 @@ function validateDirectoryName(directoryName) {
|
|
|
69
71
|
}
|
|
70
72
|
return { isValid: true };
|
|
71
73
|
}
|
|
74
|
+
function parseGitHubRepoUrl(input) {
|
|
75
|
+
const trimmed = input.trim();
|
|
76
|
+
const fullUrlMatch = trimmed.match(/^https?:\/\/github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/i);
|
|
77
|
+
if (fullUrlMatch) {
|
|
78
|
+
return `${fullUrlMatch[1]}/${fullUrlMatch[2]}`;
|
|
79
|
+
}
|
|
80
|
+
const shortUrlMatch = trimmed.match(/^github\.com\/([^/]+)\/([^/]+?)(?:\.git)?$/i);
|
|
81
|
+
if (shortUrlMatch) {
|
|
82
|
+
return `${shortUrlMatch[1]}/${shortUrlMatch[2]}`;
|
|
83
|
+
}
|
|
84
|
+
const directMatch = trimmed.match(/^([a-zA-Z0-9_.-]+)\/([a-zA-Z0-9_.-]+)$/);
|
|
85
|
+
if (directMatch) {
|
|
86
|
+
return `${directMatch[1]}/${directMatch[2]}`;
|
|
87
|
+
}
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Invalid repository format: "${input}". Expected formats: "owner/repo", "github.com/owner/repo", or "https://github.com/owner/repo"`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
async function validateRepoExists(repoPath) {
|
|
93
|
+
try {
|
|
94
|
+
await executeGhCommand(["api", `repos/${repoPath}`]);
|
|
95
|
+
return true;
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (error instanceof Error && error.message.includes("Not Found")) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
72
103
|
function validateDirectoryPath(directoryPath) {
|
|
73
104
|
const nameValidation = validateDirectoryName(directoryPath);
|
|
74
105
|
if (!nameValidation.isValid) {
|
|
@@ -102,29 +133,45 @@ var ContributeCommand = class {
|
|
|
102
133
|
/**
|
|
103
134
|
* Main entry point for the contribute command
|
|
104
135
|
* Automates fork creation, cloning, and upstream configuration
|
|
136
|
+
* @param repository - Optional repository in various formats (owner/repo, github.com/owner/repo, or full URL)
|
|
105
137
|
*/
|
|
106
|
-
async execute() {
|
|
107
|
-
|
|
138
|
+
async execute(repository) {
|
|
139
|
+
let repoPath;
|
|
140
|
+
if (repository) {
|
|
141
|
+
repoPath = parseGitHubRepoUrl(repository);
|
|
142
|
+
logger.info(`Validating repository ${chalk.cyan(repoPath)}...`);
|
|
143
|
+
const exists = await validateRepoExists(repoPath);
|
|
144
|
+
if (!exists) {
|
|
145
|
+
throw new Error(`Repository not found: ${repoPath}. Please check the repository exists and you have access.`);
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
repoPath = DEFAULT_REPO;
|
|
149
|
+
}
|
|
150
|
+
const parts = repoPath.split("/");
|
|
151
|
+
const owner = parts[0];
|
|
152
|
+
const repoName = parts[1];
|
|
153
|
+
const upstreamUrl = `https://github.com/${repoPath}.git`;
|
|
154
|
+
logger.info(chalk.bold(`Setting up contributor environment for ${chalk.cyan(repoPath)}...`));
|
|
108
155
|
const username = await this.getAuthenticatedUsername();
|
|
109
156
|
logger.success(`Authenticated as ${chalk.cyan(username)}`);
|
|
110
|
-
const hasFork = await this.forkExists(username);
|
|
157
|
+
const hasFork = await this.forkExists(username, repoName);
|
|
111
158
|
if (!hasFork) {
|
|
112
|
-
logger.info(
|
|
113
|
-
await this.createFork();
|
|
159
|
+
logger.info(`Creating fork of ${repoPath}...`);
|
|
160
|
+
await this.createFork(repoPath);
|
|
114
161
|
logger.success("Fork created successfully");
|
|
115
162
|
} else {
|
|
116
163
|
logger.info("Using existing fork");
|
|
117
164
|
}
|
|
118
|
-
const directory = await this.promptForDirectory();
|
|
165
|
+
const directory = await this.promptForDirectory(repoName);
|
|
119
166
|
if (!directory) {
|
|
120
167
|
logger.info("Setup cancelled by user");
|
|
121
168
|
process.exit(0);
|
|
122
169
|
}
|
|
123
170
|
const absolutePath = path.resolve(directory);
|
|
124
171
|
logger.info(`Cloning repository to ${directory}...`);
|
|
125
|
-
await this.cloneRepository(username, directory);
|
|
172
|
+
await this.cloneRepository(username, repoName, directory);
|
|
126
173
|
logger.success("Repository cloned successfully");
|
|
127
|
-
await this.addUpstreamRemote(absolutePath);
|
|
174
|
+
await this.addUpstreamRemote(absolutePath, upstreamUrl);
|
|
128
175
|
logger.info("Configuring iloom settings...");
|
|
129
176
|
await this.configureSettings(absolutePath);
|
|
130
177
|
logger.success("Settings configured");
|
|
@@ -132,10 +179,16 @@ var ContributeCommand = class {
|
|
|
132
179
|
logger.info(`
|
|
133
180
|
Next steps:`);
|
|
134
181
|
logger.info(` 1. cd ${directory}`);
|
|
135
|
-
|
|
136
|
-
|
|
182
|
+
if (repoPath === DEFAULT_REPO) {
|
|
183
|
+
logger.info(` 2. pnpm install`);
|
|
184
|
+
logger.info(` 3. iloom start <issue_number>`);
|
|
185
|
+
} else {
|
|
186
|
+
logger.info(` 2. See README.md or CONTRIBUTING.md for setup instructions`);
|
|
187
|
+
logger.info(` 3. If this is not a JavaScript/TypeScript project, run:`);
|
|
188
|
+
logger.info(` iloom init "help me set up iloom for this non-javascript/typescript project"`);
|
|
189
|
+
}
|
|
137
190
|
logger.info(`
|
|
138
|
-
Happy contributing!`);
|
|
191
|
+
Happy contributing to ${owner}/${repoName}!`);
|
|
139
192
|
}
|
|
140
193
|
/**
|
|
141
194
|
* Get authenticated GitHub username
|
|
@@ -160,11 +213,13 @@ Happy contributing!`);
|
|
|
160
213
|
return authStatus.username;
|
|
161
214
|
}
|
|
162
215
|
/**
|
|
163
|
-
* Check if user already has a fork of
|
|
216
|
+
* Check if user already has a fork of the target repository
|
|
217
|
+
* @param username - GitHub username
|
|
218
|
+
* @param repoName - Repository name (e.g., 'iloom-cli' from 'iloom-ai/iloom-cli')
|
|
164
219
|
*/
|
|
165
|
-
async forkExists(username) {
|
|
220
|
+
async forkExists(username, repoName) {
|
|
166
221
|
try {
|
|
167
|
-
await executeGhCommand(["api", `repos/${username}
|
|
222
|
+
await executeGhCommand(["api", `repos/${username}/${repoName}`]);
|
|
168
223
|
return true;
|
|
169
224
|
} catch (error) {
|
|
170
225
|
if (error instanceof Error && error.message.includes("Not Found")) {
|
|
@@ -174,29 +229,35 @@ Happy contributing!`);
|
|
|
174
229
|
}
|
|
175
230
|
}
|
|
176
231
|
/**
|
|
177
|
-
* Create a fork of
|
|
232
|
+
* Create a fork of the target repository without cloning
|
|
233
|
+
* @param repoPath - Full repository path (e.g., 'iloom-ai/iloom-cli')
|
|
178
234
|
*/
|
|
179
|
-
async createFork() {
|
|
180
|
-
await executeGhCommand(["repo", "fork",
|
|
235
|
+
async createFork(repoPath) {
|
|
236
|
+
await executeGhCommand(["repo", "fork", repoPath, "--clone=false"]);
|
|
181
237
|
}
|
|
182
238
|
/**
|
|
183
239
|
* Clone the repository using simplified gh CLI approach
|
|
240
|
+
* @param username - GitHub username
|
|
241
|
+
* @param repoName - Repository name (e.g., 'iloom-cli')
|
|
242
|
+
* @param directory - Target directory for clone
|
|
184
243
|
*/
|
|
185
|
-
async cloneRepository(username, directory) {
|
|
186
|
-
const repoIdentifier = `${username}
|
|
244
|
+
async cloneRepository(username, repoName, directory) {
|
|
245
|
+
const repoIdentifier = `${username}/${repoName}`;
|
|
187
246
|
await executeGhCommand(["repo", "clone", repoIdentifier, directory]);
|
|
188
247
|
}
|
|
189
248
|
/**
|
|
190
249
|
* Add upstream remote if it doesn't already exist
|
|
250
|
+
* @param directory - Cloned repository directory
|
|
251
|
+
* @param upstreamUrl - URL for the upstream remote
|
|
191
252
|
*/
|
|
192
|
-
async addUpstreamRemote(directory) {
|
|
253
|
+
async addUpstreamRemote(directory, upstreamUrl) {
|
|
193
254
|
try {
|
|
194
255
|
await executeGitCommand(["remote", "get-url", "upstream"], { cwd: directory });
|
|
195
256
|
logger.info("Upstream remote already configured");
|
|
196
257
|
} catch {
|
|
197
258
|
logger.info("Adding upstream remote...");
|
|
198
259
|
await executeGitCommand(
|
|
199
|
-
["remote", "add", "upstream",
|
|
260
|
+
["remote", "add", "upstream", upstreamUrl],
|
|
200
261
|
{ cwd: directory }
|
|
201
262
|
);
|
|
202
263
|
logger.success("Upstream remote configured");
|
|
@@ -204,15 +265,17 @@ Happy contributing!`);
|
|
|
204
265
|
}
|
|
205
266
|
/**
|
|
206
267
|
* Prompt for directory with validation and retry loop
|
|
268
|
+
* @param repoName - Repository name for default directory suggestion
|
|
207
269
|
* @returns The validated directory path, or null if user cancels
|
|
208
270
|
*/
|
|
209
|
-
async promptForDirectory() {
|
|
271
|
+
async promptForDirectory(repoName) {
|
|
210
272
|
const maxRetries = 3;
|
|
211
273
|
let attempts = 0;
|
|
274
|
+
const defaultDir = `./${repoName}`;
|
|
212
275
|
while (attempts < maxRetries) {
|
|
213
276
|
const directory = await promptInput(
|
|
214
277
|
"Where should the repository be cloned?",
|
|
215
|
-
|
|
278
|
+
defaultDir
|
|
216
279
|
);
|
|
217
280
|
if (!directory || directory.trim() === "") {
|
|
218
281
|
return null;
|
|
@@ -252,11 +315,16 @@ Happy contributing!`);
|
|
|
252
315
|
}
|
|
253
316
|
};
|
|
254
317
|
await writeFile(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
318
|
+
const firstRunManager = new FirstRunManager();
|
|
319
|
+
await firstRunManager.markProjectAsConfigured(directory);
|
|
320
|
+
logger.debug("Project marked as configured", { directory });
|
|
255
321
|
}
|
|
256
322
|
};
|
|
257
323
|
export {
|
|
258
324
|
ContributeCommand,
|
|
325
|
+
parseGitHubRepoUrl,
|
|
259
326
|
validateDirectoryName,
|
|
260
|
-
validateDirectoryPath
|
|
327
|
+
validateDirectoryPath,
|
|
328
|
+
validateRepoExists
|
|
261
329
|
};
|
|
262
|
-
//# sourceMappingURL=contribute-
|
|
330
|
+
//# sourceMappingURL=contribute-Q6GX6AXK.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/contribute.ts"],"sourcesContent":["import { logger } from '../utils/logger.js'\nimport { checkGhAuth, executeGhCommand } from '../utils/github.js'\nimport { executeGitCommand } from '../utils/git.js'\nimport { promptInput } from '../utils/prompt.js'\nimport { existsSync, accessSync, constants } from 'fs'\nimport { writeFile, mkdir } from 'fs/promises'\nimport path from 'path'\nimport { InitCommand } from './init.js'\nimport chalk from 'chalk'\nimport { FirstRunManager } from '../utils/FirstRunManager.js'\n\nconst DEFAULT_REPO = 'iloom-ai/iloom-cli'\n\n// Maximum path length for most file systems\nconst MAX_PATH_LENGTH = 255\n\n// Reserved names on Windows (also avoid on all platforms for portability)\nconst RESERVED_NAMES = [\n\t'CON', 'PRN', 'AUX', 'NUL',\n\t'COM1', 'COM2', 'COM3', 'COM4', 'COM5', 'COM6', 'COM7', 'COM8', 'COM9',\n\t'LPT1', 'LPT2', 'LPT3', 'LPT4', 'LPT5', 'LPT6', 'LPT7', 'LPT8', 'LPT9',\n]\n\n// Invalid characters for directory names (cross-platform)\n// eslint-disable-next-line no-control-regex\nconst INVALID_CHARS_PATTERN = /[<>:\"|?*\\x00-\\x1f]/\n\n\n/**\n * Validation result for directory input\n */\ninterface DirectoryValidationResult {\n\tisValid: boolean\n\terror?: string\n}\n\n/**\n * Validate directory name format\n * @param directoryName - The directory name (not full path)\n * @returns Validation result with error message if invalid\n */\nexport function validateDirectoryName(directoryName: string): DirectoryValidationResult {\n\t// Check for empty or whitespace-only\n\tif (!directoryName || directoryName.trim() === '') {\n\t\treturn { isValid: false, error: 'Directory name cannot be empty' }\n\t}\n\n\tconst trimmed = directoryName.trim()\n\tconst baseName = path.basename(trimmed)\n\n\t// Check for invalid characters\n\tif (INVALID_CHARS_PATTERN.test(baseName)) {\n\t\treturn { isValid: false, error: 'Directory name contains invalid characters (<>:\"|?*)' }\n\t}\n\n\t// Check for reserved names (case-insensitive)\n\tif (RESERVED_NAMES.includes(baseName.toUpperCase())) {\n\t\treturn { isValid: false, error: `\"${baseName}\" is a reserved name and cannot be used` }\n\t}\n\n\t// Check for names that start/end with dots or spaces (problematic on some systems)\n\tif (baseName.startsWith('.') && baseName === '.') {\n\t\treturn { isValid: false, error: 'Directory name cannot be just a dot' }\n\t}\n\tif (baseName.endsWith('.') || baseName.endsWith(' ')) {\n\t\treturn { isValid: false, error: 'Directory name cannot end with a dot or space' }\n\t}\n\n\treturn { isValid: true }\n}\n\n/**\n * Parse GitHub repository URL in multiple formats and return normalized 'owner/repo' format\n * Supported formats:\n * - Full URL: https://github.com/owner/repo\n * - Shortened: github.com/owner/repo\n * - Direct: owner/repo\n * @param input - The repository URL/identifier to parse\n * @returns Normalized 'owner/repo' format\n * @throws Error if input doesn't match any supported format\n */\nexport function parseGitHubRepoUrl(input: string): string {\n\tconst trimmed = input.trim()\n\n\t// Pattern 1: Full URL - https://github.com/owner/repo or http://github.com/owner/repo\n\tconst fullUrlMatch = trimmed.match(/^https?:\\/\\/github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?$/i)\n\tif (fullUrlMatch) {\n\t\treturn `${fullUrlMatch[1]}/${fullUrlMatch[2]}`\n\t}\n\n\t// Pattern 2: Shortened URL - github.com/owner/repo\n\tconst shortUrlMatch = trimmed.match(/^github\\.com\\/([^/]+)\\/([^/]+?)(?:\\.git)?$/i)\n\tif (shortUrlMatch) {\n\t\treturn `${shortUrlMatch[1]}/${shortUrlMatch[2]}`\n\t}\n\n\t// Pattern 3: Direct format - owner/repo (must have exactly one slash, no other special chars)\n\tconst directMatch = trimmed.match(/^([a-zA-Z0-9_.-]+)\\/([a-zA-Z0-9_.-]+)$/)\n\tif (directMatch) {\n\t\treturn `${directMatch[1]}/${directMatch[2]}`\n\t}\n\n\tthrow new Error(\n\t\t`Invalid repository format: \"${input}\". ` +\n\t\t`Expected formats: \"owner/repo\", \"github.com/owner/repo\", or \"https://github.com/owner/repo\"`\n\t)\n}\n\n/**\n * Validate that a GitHub repository exists\n * @param repoPath - Repository in 'owner/repo' format\n * @returns true if repository exists, false otherwise\n * @throws Error for unexpected API errors (not 404)\n */\nexport async function validateRepoExists(repoPath: string): Promise<boolean> {\n\ttry {\n\t\tawait executeGhCommand(['api', `repos/${repoPath}`])\n\t\treturn true\n\t} catch (error) {\n\t\t// 404 means repo doesn't exist or user doesn't have access\n\t\tif (error instanceof Error && error.message.includes('Not Found')) {\n\t\t\treturn false\n\t\t}\n\t\t// Re-throw unexpected errors\n\t\tthrow error\n\t}\n}\n\n/**\n * Validate full directory path\n * @param directoryPath - The full directory path\n * @returns Validation result with error message if invalid\n */\nexport function validateDirectoryPath(directoryPath: string): DirectoryValidationResult {\n\t// First validate the directory name component\n\tconst nameValidation = validateDirectoryName(directoryPath)\n\tif (!nameValidation.isValid) {\n\t\treturn nameValidation\n\t}\n\n\tconst trimmed = directoryPath.trim()\n\tconst absolutePath = path.resolve(trimmed)\n\n\t// Check path length\n\tif (absolutePath.length > MAX_PATH_LENGTH) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: `Path is too long (${absolutePath.length} characters). Maximum is ${MAX_PATH_LENGTH} characters.`\n\t\t}\n\t}\n\n\t// Check if directory already exists\n\tif (existsSync(absolutePath)) {\n\t\treturn { isValid: false, error: `Directory already exists: ${trimmed}` }\n\t}\n\n\t// Check if parent directory exists\n\tconst parentDir = path.dirname(absolutePath)\n\tif (!existsSync(parentDir)) {\n\t\treturn { isValid: false, error: `Parent directory does not exist: ${parentDir}` }\n\t}\n\n\t// Check if parent directory is writable\n\ttry {\n\t\taccessSync(parentDir, constants.W_OK)\n\t} catch {\n\t\treturn { isValid: false, error: `Parent directory is not writable: ${parentDir}` }\n\t}\n\n\treturn { isValid: true }\n}\n\n\n/**\n * ContributeCommand - Set up local development environment for contributing to iloom\n * Implements issue #220: streamlined contributor onboarding workflow\n */\nexport class ContributeCommand {\n\tconstructor(_initCommand?: InitCommand) {}\n\n\t/**\n\t * Main entry point for the contribute command\n\t * Automates fork creation, cloning, and upstream configuration\n\t * @param repository - Optional repository in various formats (owner/repo, github.com/owner/repo, or full URL)\n\t */\n\tpublic async execute(repository?: string): Promise<void> {\n\t\t// Parse and validate repository if provided, otherwise use default\n\t\tlet repoPath: string\n\t\tif (repository) {\n\t\t\trepoPath = parseGitHubRepoUrl(repository)\n\t\t\tlogger.info(`Validating repository ${chalk.cyan(repoPath)}...`)\n\t\t\tconst exists = await validateRepoExists(repoPath)\n\t\t\tif (!exists) {\n\t\t\t\tthrow new Error(`Repository not found: ${repoPath}. Please check the repository exists and you have access.`)\n\t\t\t}\n\t\t} else {\n\t\t\trepoPath = DEFAULT_REPO\n\t\t}\n\n\t\t// Extract owner and repo name from path (guaranteed to be valid format after parseGitHubRepoUrl)\n\t\tconst parts = repoPath.split('/')\n\t\tconst owner = parts[0] as string\n\t\tconst repoName = parts[1] as string\n\t\tconst upstreamUrl = `https://github.com/${repoPath}.git`\n\n\t\tlogger.info(chalk.bold(`Setting up contributor environment for ${chalk.cyan(repoPath)}...`))\n\n\t\t// Step 1: Verify gh CLI authenticated\n\t\tconst username = await this.getAuthenticatedUsername()\n\t\tlogger.success(`Authenticated as ${chalk.cyan(username)}`)\n\n\t\t// Step 2: Check for existing fork\n\t\tconst hasFork = await this.forkExists(username, repoName)\n\n\t\t// Step 3: Create fork if needed\n\t\tif (!hasFork) {\n\t\t\tlogger.info(`Creating fork of ${repoPath}...`)\n\t\t\tawait this.createFork(repoPath)\n\t\t\tlogger.success('Fork created successfully')\n\t\t} else {\n\t\t\tlogger.info('Using existing fork')\n\t\t}\n\n\t\t// Step 4: Prompt for directory with validation and retry loop\n\t\tconst directory = await this.promptForDirectory(repoName)\n\n\t\t// Handle cancelled input\n\t\tif (!directory) {\n\t\t\tlogger.info('Setup cancelled by user')\n\t\t\tprocess.exit(0)\n\t\t}\n\n\t\tconst absolutePath = path.resolve(directory)\n\n\t\t// Step 5: Clone repository (gh CLI handles SSH/HTTPS automatically based on git config)\n\t\tlogger.info(`Cloning repository to ${directory}...`)\n\t\tawait this.cloneRepository(username, repoName, directory)\n\t\tlogger.success('Repository cloned successfully')\n\n\t\t// Step 6: Add upstream remote if it doesn't exist\n\t\tawait this.addUpstreamRemote(absolutePath, upstreamUrl)\n\n\t\t// Step 7: Configure settings\n\t\tlogger.info('Configuring iloom settings...')\n\t\tawait this.configureSettings(absolutePath)\n\t\tlogger.success('Settings configured')\n\n\t\tlogger.success(chalk.bold.green('\\nContributor environment setup complete!'))\n\t\tlogger.info(`\\nNext steps:`)\n\t\tlogger.info(` 1. cd ${directory}`)\n\t\tif (repoPath === DEFAULT_REPO) {\n\t\t\tlogger.info(` 2. pnpm install`)\n\t\t\tlogger.info(` 3. iloom start <issue_number>`)\n\t\t} else {\n\t\t\tlogger.info(` 2. See README.md or CONTRIBUTING.md for setup instructions`)\n\t\t\tlogger.info(` 3. If this is not a JavaScript/TypeScript project, run:`)\n\t\t\tlogger.info(` iloom init \"help me set up iloom for this non-javascript/typescript project\"`)\n\t\t}\n\t\tlogger.info(`\\nHappy contributing to ${owner}/${repoName}!`)\n\t}\n\n\t/**\n\t * Get authenticated GitHub username\n\t * @throws Error if not authenticated\n\t */\n\tprivate async getAuthenticatedUsername(): Promise<string> {\n\t\tconst authStatus = await checkGhAuth()\n\n\t\tif (!authStatus.hasAuth) {\n\t\t\tthrow new Error(\n\t\t\t\t'GitHub CLI is not authenticated. Please run: gh auth login'\n\t\t\t)\n\t\t}\n\n\t\tif (!authStatus.username) {\n\t\t\t// Try to fetch username from gh api if not in auth status\n\t\t\ttry {\n\t\t\t\tconst user = await executeGhCommand<{ login: string }>(['api', 'user', '--json', 'login'])\n\t\t\t\treturn user.login\n\t\t\t} catch (error) {\n\t\t\t\tconst message = error instanceof Error ? error.message : String(error)\n\t\t\t\tthrow new Error(`Unable to determine GitHub username: ${message}`)\n\t\t\t}\n\t\t}\n\n\t\treturn authStatus.username\n\t}\n\n\t/**\n\t * Check if user already has a fork of the target repository\n\t * @param username - GitHub username\n\t * @param repoName - Repository name (e.g., 'iloom-cli' from 'iloom-ai/iloom-cli')\n\t */\n\tprivate async forkExists(username: string, repoName: string): Promise<boolean> {\n\t\ttry {\n\t\t\tawait executeGhCommand(['api', `repos/${username}/${repoName}`])\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\t// 404 means no fork exists\n\t\t\tif (error instanceof Error && error.message.includes('Not Found')) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\t// Re-throw unexpected errors\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Create a fork of the target repository without cloning\n\t * @param repoPath - Full repository path (e.g., 'iloom-ai/iloom-cli')\n\t */\n\tprivate async createFork(repoPath: string): Promise<void> {\n\t\tawait executeGhCommand(['repo', 'fork', repoPath, '--clone=false'])\n\t}\n\n\n\t/**\n\t * Clone the repository using simplified gh CLI approach\n\t * @param username - GitHub username\n\t * @param repoName - Repository name (e.g., 'iloom-cli')\n\t * @param directory - Target directory for clone\n\t */\n\tprivate async cloneRepository(\n\t\tusername: string,\n\t\trepoName: string,\n\t\tdirectory: string\n\t): Promise<void> {\n\t\tconst repoIdentifier = `${username}/${repoName}`\n\t\t// Always use gh repo clone - it handles SSH/HTTPS based on user's git config\n\t\tawait executeGhCommand(['repo', 'clone', repoIdentifier, directory])\n\t}\n\n\t/**\n\t * Add upstream remote if it doesn't already exist\n\t * @param directory - Cloned repository directory\n\t * @param upstreamUrl - URL for the upstream remote\n\t */\n\tprivate async addUpstreamRemote(directory: string, upstreamUrl: string): Promise<void> {\n\t\ttry {\n\t\t\t// Check if upstream remote exists\n\t\t\tawait executeGitCommand(['remote', 'get-url', 'upstream'], { cwd: directory })\n\t\t\tlogger.info('Upstream remote already configured')\n\t\t} catch {\n\t\t\t// Upstream doesn't exist, add it\n\t\t\tlogger.info('Adding upstream remote...')\n\t\t\tawait executeGitCommand(\n\t\t\t\t['remote', 'add', 'upstream', upstreamUrl],\n\t\t\t\t{ cwd: directory }\n\t\t\t)\n\t\t\tlogger.success('Upstream remote configured')\n\t\t}\n\t}\n\n\t/**\n\t * Prompt for directory with validation and retry loop\n\t * @param repoName - Repository name for default directory suggestion\n\t * @returns The validated directory path, or null if user cancels\n\t */\n\tprivate async promptForDirectory(repoName: string): Promise<string | null> {\n\t\tconst maxRetries = 3\n\t\tlet attempts = 0\n\t\tconst defaultDir = `./${repoName}`\n\n\t\twhile (attempts < maxRetries) {\n\t\t\tconst directory = await promptInput(\n\t\t\t\t'Where should the repository be cloned?',\n\t\t\t\tdefaultDir\n\t\t\t)\n\n\t\t\t// Handle empty input (user cancelled by entering empty string after exhausting default)\n\t\t\tif (!directory || directory.trim() === '') {\n\t\t\t\treturn null\n\t\t\t}\n\n\t\t\tconst trimmed = directory.trim()\n\n\t\t\t// Validate the directory path\n\t\t\tconst validation = validateDirectoryPath(trimmed)\n\t\t\tif (validation.isValid) {\n\t\t\t\treturn trimmed\n\t\t\t}\n\n\t\t\t// Show error and increment attempts\n\t\t\tattempts++\n\t\t\tif (attempts < maxRetries) {\n\t\t\t\tlogger.error(`${validation.error}`)\n\t\t\t\tlogger.info(`Please try again (${maxRetries - attempts} attempts remaining)`)\n\t\t\t} else {\n\t\t\t\tlogger.error(`${validation.error}`)\n\t\t\t\tlogger.error('Maximum retry attempts reached')\n\t\t\t\tthrow new Error(`Invalid directory after ${maxRetries} attempts: ${validation.error}`)\n\t\t\t}\n\t\t}\n\n\t\treturn null\n\t}\n\n\n\t/**\n\t * Configure .iloom/settings.json with upstream remote\n\t */\n\tprivate async configureSettings(directory: string): Promise<void> {\n\t\tconst iloomDir = path.join(directory, '.iloom')\n\t\tconst settingsPath = path.join(iloomDir, 'settings.local.json')\n\n\t\t// Create .iloom directory\n\t\tawait mkdir(iloomDir, { recursive: true })\n\n\t\t// Create settings.json with upstream remote configuration and github-pr mode\n\t\tconst settings = {\n\t\t\tissueManagement: {\n\t\t\t\tgithub: {\n\t\t\t\t\tremote: 'upstream',\n\t\t\t\t},\n\t\t\t},\n\t\t\tmergeBehavior: {\n\t\t\t\tmode: 'github-draft-pr',\n\t\t\t},\n\t\t}\n\n\t\tawait writeFile(settingsPath, JSON.stringify(settings, null, 2) + '\\n')\n\n\t\t// Mark project as configured for il projects list and VSCode extension detection\n\t\tconst firstRunManager = new FirstRunManager()\n\t\tawait firstRunManager.markProjectAsConfigured(directory)\n\t\tlogger.debug('Project marked as configured', { directory })\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
InitCommand
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-LVBRMTE6.js";
|
|
5
5
|
import "./chunk-Q7POFB5Q.js";
|
|
6
6
|
import "./chunk-F2PWIRV4.js";
|
|
7
7
|
import "./chunk-SN3Z6EZO.js";
|
|
@@ -18,4 +18,4 @@ import "./chunk-VT4PDUYT.js";
|
|
|
18
18
|
export {
|
|
19
19
|
InitCommand
|
|
20
20
|
};
|
|
21
|
-
//# sourceMappingURL=init-
|
|
21
|
+
//# sourceMappingURL=init-UTYRHNJJ.js.map
|
|
@@ -1150,14 +1150,7 @@ Reason: mainBranch has same value in both files, so it's removed from local
|
|
|
1150
1150
|
- `.iloom/settings.local.json` if user chose Local
|
|
1151
1151
|
4. Use the Write tool to create/update the file
|
|
1152
1152
|
|
|
1153
|
-
### Phase 7:
|
|
1154
|
-
|
|
1155
|
-
If the user chose `.iloom/settings.local.json`, ensure `.gitignore` includes this entry:
|
|
1156
|
-
- Read `.gitignore` if it exists
|
|
1157
|
-
- Check if `.iloom/settings.local.json` is already listed
|
|
1158
|
-
- If not, append it to the file
|
|
1159
|
-
|
|
1160
|
-
### Phase 7.5: Offer to Commit Changes
|
|
1153
|
+
### Phase 7: Offer to Commit Changes
|
|
1161
1154
|
|
|
1162
1155
|
After making configuration changes, offer to commit the iloom-related files:
|
|
1163
1156
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
MergeManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2A7WQKBE.js";
|
|
5
5
|
import {
|
|
6
6
|
GitWorktreeManager
|
|
7
7
|
} from "./chunk-EK3XCAAS.js";
|
|
@@ -94,4 +94,4 @@ export {
|
|
|
94
94
|
RebaseCommand,
|
|
95
95
|
WorktreeValidationError
|
|
96
96
|
};
|
|
97
|
-
//# sourceMappingURL=rebase-
|
|
97
|
+
//# sourceMappingURL=rebase-Y4AS6LQW.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iloom/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Control plane for maintaining alignment between you and Claude Code as you work across multiple issues using isolated environments, visible context, and multi-agent workflows to scale understanding, not just output",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|