create-egregore 0.5.0 → 0.6.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.
Files changed (3) hide show
  1. package/bin/cli.js +30 -1
  2. package/lib/local.js +63 -5
  3. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -13,7 +13,7 @@
13
13
  const ui = require("../lib/ui");
14
14
  const { EgregoreAPI } = require("../lib/api");
15
15
  const { deviceFlow } = require("../lib/auth");
16
- const { install } = require("../lib/setup");
16
+ const { install, ghApi } = require("../lib/setup");
17
17
 
18
18
  const API_URL = process.env.EGREGORE_API_URL || "https://egregore-production-55f2.up.railway.app";
19
19
 
@@ -255,6 +255,35 @@ async function setupFlow(api, githubToken, choice) {
255
255
  // Non-fatal — continue without repos
256
256
  }
257
257
 
258
+ // Offer to create a new project repo
259
+ console.log("");
260
+ const newRepoName = await ui.prompt("Create a new project repo? Enter name (or press Enter to skip):");
261
+ if (newRepoName) {
262
+ const repoSlug = newRepoName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
263
+ if (repoSlug) {
264
+ const s2 = ui.spinner(`Creating ${repoSlug}...`);
265
+ try {
266
+ const apiPath = choice.is_personal ? "/user/repos" : `/orgs/${choice.login}/repos`;
267
+ const { status } = await ghApi("POST", apiPath, githubToken, {
268
+ name: repoSlug,
269
+ private: true,
270
+ auto_init: true,
271
+ });
272
+ if (status === 201 || status === 200) {
273
+ selectedRepos.push(repoSlug);
274
+ s2.stop(`Created ${repoSlug}`);
275
+ } else if (status === 422) {
276
+ selectedRepos.push(repoSlug);
277
+ s2.stop(`${repoSlug} already exists — added to managed repos`);
278
+ } else {
279
+ s2.fail(`Could not create ${repoSlug}`);
280
+ }
281
+ } catch (err) {
282
+ s2.fail(`Could not create ${repoSlug}: ${err.message}`);
283
+ }
284
+ }
285
+ }
286
+
258
287
  // Transcript sharing consent
259
288
  console.log("");
260
289
  console.log(" Egregore can collect session transcripts to build");
package/lib/local.js CHANGED
@@ -214,7 +214,7 @@ async function localFounderFlow(ui) {
214
214
  }
215
215
 
216
216
  // 5. Collect project info
217
- let orgName, description, selectedRepos = [];
217
+ let orgName, description, selectedRepos = [], newProjectRepo = null;
218
218
 
219
219
  if (isNewProject) {
220
220
  const nameInput = await ui.prompt("What's your team called?");
@@ -222,6 +222,34 @@ async function localFounderFlow(ui) {
222
222
 
223
223
  const descInput = await ui.prompt("What are you building? (one line)");
224
224
  description = descInput || "";
225
+
226
+ // Ask about project repo
227
+ console.log("");
228
+ const projectAction = await ui.choose("Do you have a project repo?", [
229
+ { label: "Create a new repo", description: "Start fresh — we'll create it on GitHub" },
230
+ { label: "Connect an existing repo", description: "I already have code" },
231
+ { label: "Skip for now", description: "I'll add projects later" },
232
+ ]);
233
+
234
+ if (projectAction.label.startsWith("Create")) {
235
+ const projectName = await ui.prompt("Repo name:");
236
+ if (projectName) {
237
+ newProjectRepo = projectName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
238
+ }
239
+ } else if (projectAction.label.startsWith("Connect")) {
240
+ const s0 = ui.spinner("Loading repos...");
241
+ try {
242
+ const repos = await listOrgRepos(githubToken, githubOrg);
243
+ s0.stop("Loaded repos");
244
+ if (repos.length > 0) {
245
+ selectedRepos = await ui.multiSelect("Which repos should Egregore manage?", repos);
246
+ } else {
247
+ ui.info("No repos found in this org yet.");
248
+ }
249
+ } catch {
250
+ s0.stop("Could not load repos");
251
+ }
252
+ }
225
253
  } else {
226
254
  // "Connect existing repos"
227
255
  const nameInput = await ui.prompt(`Display name [${githubOrg}]:`);
@@ -301,6 +329,33 @@ async function localFounderFlow(ui) {
301
329
  }
302
330
  }
303
331
 
332
+ // 7b. Create project repo (if requested)
333
+ if (newProjectRepo) {
334
+ if (newProjectRepo === repoName || newProjectRepo === memoryRepoName) {
335
+ ui.warn(`"${newProjectRepo}" conflicts with Egregore repo names — skipping`);
336
+ newProjectRepo = null;
337
+ } else {
338
+ const s3 = ui.spinner(`Creating ${newProjectRepo}...`);
339
+ const projExists = await repoExists(githubToken, githubOrg, newProjectRepo);
340
+ if (projExists) {
341
+ selectedRepos.push(newProjectRepo);
342
+ s3.stop(`${newProjectRepo} already exists — added to managed repos`);
343
+ } else {
344
+ try {
345
+ await createRepo(githubToken, githubOrg, newProjectRepo, isOrg, description || "");
346
+ if (await waitForRepo(githubToken, githubOrg, newProjectRepo)) {
347
+ selectedRepos.push(newProjectRepo);
348
+ s3.stop(`Created ${newProjectRepo}`);
349
+ } else {
350
+ s3.fail(`${newProjectRepo} creation timed out`);
351
+ }
352
+ } catch (err) {
353
+ s3.fail(`Could not create ${newProjectRepo}: ${err.message}`);
354
+ }
355
+ }
356
+ }
357
+ }
358
+
304
359
  // 8. Write egregore.json to remote repo (so joiners can read it)
305
360
  const egreConfig = {
306
361
  org_name: orgName,
@@ -419,10 +474,13 @@ async function localFounderFlow(ui) {
419
474
 
420
475
  // 18. Telegram group setup (optional)
421
476
  console.log("");
422
- ui.info("Egregore can send notifications to a Telegram group.");
423
- ui.info("Create a group, add @egregore_bot, and paste the invite link.");
477
+ ui.info("Want notifications? Set up a Telegram group:");
478
+ ui.info("");
479
+ ui.info(` 1. Create a Telegram group for your team`);
480
+ ui.info(` 2. Add the bot: ${ui.cyan("https://t.me/egregore_bot")}`);
481
+ ui.info(` 3. Paste the group invite link below`);
424
482
  console.log("");
425
- const telegramLink = await ui.prompt("Telegram group invite link (Enter to skip):");
483
+ const telegramLink = await ui.prompt("Group invite link (Enter to skip):");
426
484
  if (telegramLink) {
427
485
  egreConfig.telegram_group_link = telegramLink;
428
486
  // Update local egregore.json
@@ -680,4 +738,4 @@ async function localJoinFlow(orgArg, ui) {
680
738
  console.log("");
681
739
  }
682
740
 
683
- module.exports = { localFounderFlow, localJoinFlow, addCollaborator, getUser, repoExists };
741
+ module.exports = { localFounderFlow, localJoinFlow, addCollaborator, getUser, repoExists, createRepo, waitForRepo };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-egregore",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Set up Egregore for your team in one command",
5
5
  "license": "MIT",
6
6
  "bin": {