create-egregore 0.6.1 → 0.7.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/lib/auth.js +4 -1
- package/lib/local.js +35 -49
- package/package.json +1 -1
package/lib/auth.js
CHANGED
|
@@ -91,12 +91,15 @@ async function deviceFlow(ui) {
|
|
|
91
91
|
// 2. Show code + open browser
|
|
92
92
|
const copied = copyToClipboard(user_code);
|
|
93
93
|
ui.info("");
|
|
94
|
+
ui.info("A GitHub page will open. Just click Authorize — you'll choose");
|
|
95
|
+
ui.info("where to set up Egregore in the next step.");
|
|
96
|
+
ui.info("");
|
|
94
97
|
if (copied) {
|
|
95
98
|
ui.info(`Code copied to clipboard: ${ui.bold(user_code)}`);
|
|
96
99
|
} else {
|
|
97
100
|
ui.info(`Your code: ${ui.bold(user_code)}`);
|
|
98
101
|
}
|
|
99
|
-
ui.info("Opening browser
|
|
102
|
+
ui.info("Opening browser...");
|
|
100
103
|
ui.info("");
|
|
101
104
|
openBrowser(verifyUrl);
|
|
102
105
|
|
package/lib/local.js
CHANGED
|
@@ -104,8 +104,9 @@ async function putFileContent(token, owner, repo, filePath, content, message) {
|
|
|
104
104
|
return ghApi("PUT", `/repos/${owner}/${repo}/contents/${filePath}`, token, body);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
async function listOrgRepos(token,
|
|
108
|
-
const
|
|
107
|
+
async function listOrgRepos(token, owner, isOrg) {
|
|
108
|
+
const apiPath = isOrg ? `/orgs/${owner}/repos?per_page=100&sort=updated` : `/users/${owner}/repos?per_page=100&sort=updated&type=owner`;
|
|
109
|
+
const { status, data } = await ghApi("GET", apiPath, token);
|
|
109
110
|
if (status !== 200 || !Array.isArray(data)) return [];
|
|
110
111
|
return data
|
|
111
112
|
.filter((r) => !r.archived && r.name !== "egregore" && r.name !== "egregore-core" && !r.name.endsWith("-memory"))
|
|
@@ -180,14 +181,7 @@ async function localFounderFlow(ui) {
|
|
|
180
181
|
// 2. Get user info
|
|
181
182
|
const user = await getUser(githubToken);
|
|
182
183
|
|
|
183
|
-
// 3.
|
|
184
|
-
const action = await ui.choose("What do you want to do?", [
|
|
185
|
-
{ label: "Start a new project", description: "Create repos and shared memory" },
|
|
186
|
-
{ label: "Connect existing repos", description: "Set up Egregore for an org you manage" },
|
|
187
|
-
]);
|
|
188
|
-
const isNewProject = action.label.startsWith("Start");
|
|
189
|
-
|
|
190
|
-
// 4. Detect GitHub org
|
|
184
|
+
// 3. Where — always show picker (personal first)
|
|
191
185
|
console.log("");
|
|
192
186
|
const s = ui.spinner("Checking your GitHub accounts...");
|
|
193
187
|
const orgs = await listOrgs(githubToken);
|
|
@@ -195,29 +189,31 @@ async function localFounderFlow(ui) {
|
|
|
195
189
|
|
|
196
190
|
let githubOrg, isOrg;
|
|
197
191
|
if (orgs.length === 0) {
|
|
198
|
-
// No orgs — use personal account
|
|
199
192
|
githubOrg = user.login;
|
|
200
193
|
isOrg = false;
|
|
201
194
|
ui.info(`Using personal account: ${ui.bold(githubOrg)}`);
|
|
202
|
-
} else if (orgs.length === 1) {
|
|
203
|
-
// One org — use it automatically
|
|
204
|
-
githubOrg = orgs[0].login;
|
|
205
|
-
isOrg = true;
|
|
206
|
-
ui.info(`Using organization: ${ui.bold(githubOrg)}`);
|
|
207
195
|
} else {
|
|
208
|
-
|
|
209
|
-
const
|
|
210
|
-
|
|
211
|
-
|
|
196
|
+
const orgChoices = [{ label: user.login, description: "Personal account" }];
|
|
197
|
+
for (const o of orgs) {
|
|
198
|
+
orgChoices.push({ label: o.login, description: "Organization" });
|
|
199
|
+
}
|
|
200
|
+
const orgChoice = await ui.choose("Where do you want to set up Egregore?", orgChoices);
|
|
212
201
|
githubOrg = orgChoice.label;
|
|
213
202
|
isOrg = githubOrg !== user.login;
|
|
214
203
|
}
|
|
215
204
|
|
|
205
|
+
// 4. What — new or existing?
|
|
206
|
+
const action = await ui.choose("What are you working on?", [
|
|
207
|
+
{ label: "Starting something new", description: "Create a project from scratch" },
|
|
208
|
+
{ label: "Existing project", description: "Connect repos I already have" },
|
|
209
|
+
]);
|
|
210
|
+
const isNewProject = action.label.startsWith("Starting");
|
|
211
|
+
|
|
216
212
|
// 5. Collect project info
|
|
217
213
|
let orgName, description, selectedRepos = [], newProjectRepo = null;
|
|
218
214
|
|
|
219
215
|
if (isNewProject) {
|
|
220
|
-
const nameInput = await ui.prompt("What's your team called?");
|
|
216
|
+
const nameInput = await ui.prompt("What's your team or project called?");
|
|
221
217
|
orgName = nameInput || githubOrg;
|
|
222
218
|
|
|
223
219
|
const descInput = await ui.prompt("What are you building? (one line)");
|
|
@@ -225,44 +221,32 @@ async function localFounderFlow(ui) {
|
|
|
225
221
|
|
|
226
222
|
// Ask about project repo
|
|
227
223
|
console.log("");
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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
|
-
}
|
|
224
|
+
ui.info("Egregore creates its own repo for shared memory and config.");
|
|
225
|
+
ui.info("Want to also create a repo for your actual project code?");
|
|
226
|
+
console.log("");
|
|
227
|
+
const projectName = await ui.prompt("Project repo name (Enter to skip):");
|
|
228
|
+
if (projectName) {
|
|
229
|
+
newProjectRepo = projectName.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
252
230
|
}
|
|
253
231
|
} else {
|
|
254
|
-
// "
|
|
255
|
-
const nameInput = await ui.prompt(`
|
|
232
|
+
// "Existing project"
|
|
233
|
+
const nameInput = await ui.prompt(`What should we call this Egregore? [${githubOrg}]:`);
|
|
256
234
|
orgName = nameInput || githubOrg;
|
|
257
235
|
description = "";
|
|
258
236
|
|
|
259
237
|
// Multi-select repos to manage
|
|
238
|
+
const s0 = ui.spinner("Loading repos...");
|
|
260
239
|
try {
|
|
261
|
-
const repos = await listOrgRepos(githubToken, githubOrg);
|
|
240
|
+
const repos = await listOrgRepos(githubToken, githubOrg, isOrg);
|
|
241
|
+
s0.stop("Loaded repos");
|
|
262
242
|
if (repos.length > 0) {
|
|
263
243
|
selectedRepos = await ui.multiSelect("Which repos should Egregore manage?", repos);
|
|
244
|
+
} else {
|
|
245
|
+
ui.info("No repos found yet.");
|
|
264
246
|
}
|
|
265
|
-
} catch {
|
|
247
|
+
} catch {
|
|
248
|
+
s0.stop("Could not load repos");
|
|
249
|
+
}
|
|
266
250
|
}
|
|
267
251
|
|
|
268
252
|
// 6. Derive repo names from team name
|
|
@@ -365,6 +349,8 @@ async function localFounderFlow(ui) {
|
|
|
365
349
|
org_name: orgName,
|
|
366
350
|
github_org: githubOrg,
|
|
367
351
|
memory_repo: `https://github.com/${githubOrg}/${memoryRepoName}.git`,
|
|
352
|
+
slug: slug,
|
|
353
|
+
repo_name: repoName,
|
|
368
354
|
repos: selectedRepos,
|
|
369
355
|
};
|
|
370
356
|
try {
|