create-hq 10.10.0 → 10.12.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 (59) hide show
  1. package/commands/{team-sync.md → sync-team.md} +167 -6
  2. package/dist/__tests__/auth.test.js +176 -186
  3. package/dist/__tests__/auth.test.js.map +1 -1
  4. package/dist/__tests__/scaffold.test.js +5 -3
  5. package/dist/__tests__/scaffold.test.js.map +1 -1
  6. package/dist/auth.d.ts +57 -129
  7. package/dist/auth.d.ts.map +1 -1
  8. package/dist/auth.js +81 -370
  9. package/dist/auth.js.map +1 -1
  10. package/dist/fetch-template.d.ts +7 -2
  11. package/dist/fetch-template.d.ts.map +1 -1
  12. package/dist/fetch-template.js +27 -15
  13. package/dist/fetch-template.js.map +1 -1
  14. package/dist/index.js +7 -17
  15. package/dist/index.js.map +1 -1
  16. package/dist/packages.d.ts.map +1 -1
  17. package/dist/packages.js +1 -1
  18. package/dist/packages.js.map +1 -1
  19. package/dist/recommended-packages.d.ts +93 -0
  20. package/dist/recommended-packages.d.ts.map +1 -0
  21. package/dist/recommended-packages.js +221 -0
  22. package/dist/recommended-packages.js.map +1 -0
  23. package/dist/scaffold.d.ts +4 -2
  24. package/dist/scaffold.d.ts.map +1 -1
  25. package/dist/scaffold.js +127 -232
  26. package/dist/scaffold.js.map +1 -1
  27. package/dist/ui.d.ts +0 -17
  28. package/dist/ui.d.ts.map +1 -1
  29. package/dist/ui.js +0 -45
  30. package/dist/ui.js.map +1 -1
  31. package/package.json +2 -1
  32. package/dist/admin-onboarding.d.ts +0 -44
  33. package/dist/admin-onboarding.d.ts.map +0 -1
  34. package/dist/admin-onboarding.js +0 -530
  35. package/dist/admin-onboarding.js.map +0 -1
  36. package/dist/company-template.d.ts +0 -34
  37. package/dist/company-template.d.ts.map +0 -1
  38. package/dist/company-template.js +0 -142
  39. package/dist/company-template.js.map +0 -1
  40. package/dist/invite-command.d.ts +0 -10
  41. package/dist/invite-command.d.ts.map +0 -1
  42. package/dist/invite-command.js +0 -110
  43. package/dist/invite-command.js.map +0 -1
  44. package/dist/invite.d.ts +0 -91
  45. package/dist/invite.d.ts.map +0 -1
  46. package/dist/invite.js +0 -230
  47. package/dist/invite.js.map +0 -1
  48. package/dist/join-flow.d.ts +0 -32
  49. package/dist/join-flow.d.ts.map +0 -1
  50. package/dist/join-flow.js +0 -315
  51. package/dist/join-flow.js.map +0 -1
  52. package/dist/team-setup.d.ts +0 -83
  53. package/dist/team-setup.d.ts.map +0 -1
  54. package/dist/team-setup.js +0 -353
  55. package/dist/team-setup.js.map +0 -1
  56. package/dist/teams-flow.d.ts +0 -41
  57. package/dist/teams-flow.d.ts.map +0 -1
  58. package/dist/teams-flow.js +0 -173
  59. package/dist/teams-flow.js.map +0 -1
package/dist/invite.js DELETED
@@ -1,230 +0,0 @@
1
- /**
2
- * Invite system for HQ Teams.
3
- *
4
- * Tokens are self-contained (no server) — they encode the team coordinates
5
- * so a new member can join without discovery. Security comes from GitHub:
6
- * the member still needs org access to clone the private repo.
7
- *
8
- * Token format: "hq_" + base64url({ org, repo, slug, teamName, cloneUrl, invitedBy })
9
- *
10
- * Admin flow:
11
- * 1. Generate token from team metadata
12
- * 2. Optionally send GitHub org invite by email
13
- * 3. Share token + instructions with member
14
- *
15
- * Member flow:
16
- * 1. Decode token → get team coordinates
17
- * 2. Auth via GitHub device flow
18
- * 3. Verify org membership (wait for invite acceptance if needed)
19
- * 4. Clone repo into companies/{slug}/
20
- */
21
- import chalk from "chalk";
22
- import { execSync } from "child_process";
23
- import { githubApi, openBrowser } from "./auth.js";
24
- // ─── Token encode / decode ──────────────────────────────────────────────────
25
- const TOKEN_PREFIX = "hq_";
26
- function toBase64Url(str) {
27
- return Buffer.from(str, "utf-8")
28
- .toString("base64")
29
- .replace(/\+/g, "-")
30
- .replace(/\//g, "_")
31
- .replace(/=+$/, "");
32
- }
33
- function fromBase64Url(b64) {
34
- const padded = b64.replace(/-/g, "+").replace(/_/g, "/");
35
- return Buffer.from(padded, "base64").toString("utf-8");
36
- }
37
- export function encodeInviteToken(payload) {
38
- return TOKEN_PREFIX + toBase64Url(JSON.stringify(payload));
39
- }
40
- export function decodeInviteToken(token) {
41
- try {
42
- const raw = token.startsWith(TOKEN_PREFIX)
43
- ? token.slice(TOKEN_PREFIX.length)
44
- : token;
45
- const json = fromBase64Url(raw);
46
- const parsed = JSON.parse(json);
47
- // Validate required fields
48
- if (typeof parsed.org !== "string" ||
49
- typeof parsed.repo !== "string" ||
50
- typeof parsed.slug !== "string" ||
51
- typeof parsed.teamName !== "string" ||
52
- typeof parsed.cloneUrl !== "string" ||
53
- typeof parsed.invitedBy !== "string") {
54
- return null;
55
- }
56
- return parsed;
57
- }
58
- catch {
59
- return null;
60
- }
61
- }
62
- /**
63
- * Send a GitHub org invitation by email.
64
- *
65
- * Requires the authenticated user to be an org admin, and the GitHub App
66
- * to have "Organization > Members: Write" permission.
67
- *
68
- * Returns the invitation on success, or an error message string on failure.
69
- */
70
- export async function sendOrgInviteByEmail(auth, orgLogin, email, role = "direct_member") {
71
- try {
72
- const invite = await githubApi(`/orgs/${orgLogin}/invitations`, auth, {
73
- method: "POST",
74
- body: JSON.stringify({
75
- email,
76
- role,
77
- }),
78
- });
79
- return { ok: true, invite };
80
- }
81
- catch (err) {
82
- const message = err instanceof Error ? err.message : String(err);
83
- if (message.includes("404") || message.includes("403")) {
84
- return {
85
- ok: false,
86
- error: "The HQ App doesn't have permission to send org invites. " +
87
- `Please invite the member manually at: https://github.com/orgs/${orgLogin}/people`,
88
- };
89
- }
90
- if (message.includes("422") && /already/i.test(message)) {
91
- return {
92
- ok: false,
93
- error: "This email has already been invited or is already a member.",
94
- };
95
- }
96
- return { ok: false, error: message };
97
- }
98
- }
99
- /**
100
- * Check whether a GitHub user is a member of an org.
101
- */
102
- export async function checkOrgMembership(auth, orgLogin, username) {
103
- // Check active membership first
104
- try {
105
- await githubApi(`/orgs/${orgLogin}/members/${username}`, auth);
106
- return "active";
107
- }
108
- catch {
109
- // Not an active member — check pending invitations
110
- }
111
- // Check if there's a pending invitation for this user
112
- try {
113
- const memberships = await githubApi("/user/memberships/orgs?state=pending&per_page=100", auth);
114
- const pending = memberships.find((m) => m.organization.login.toLowerCase() === orgLogin.toLowerCase());
115
- if (pending)
116
- return "pending";
117
- }
118
- catch {
119
- // Can't check pending — fall through
120
- }
121
- return "none";
122
- }
123
- /**
124
- * Check whether the authenticated user can access a specific repo.
125
- */
126
- export async function checkRepoAccess(auth, orgLogin, repoName) {
127
- try {
128
- await githubApi(`/repos/${orgLogin}/${repoName}`, auth);
129
- return true;
130
- }
131
- catch {
132
- return false;
133
- }
134
- }
135
- // ─── Invite message template ────────────────────────────────────────────────
136
- /**
137
- * Generate a ready-to-share invite message for the admin to send to the
138
- * new member. Designed to be copy-pasted into Slack, email, or text.
139
- */
140
- export function formatInviteMessage(payload, token, memberEmail) {
141
- const orgInviteUrl = `https://github.com/orgs/${payload.org}/invitation`;
142
- const lines = [
143
- `You've been invited to join ${payload.teamName} on HQ!`,
144
- "",
145
- ];
146
- // Step 1: Accept org invite (which handles GitHub account creation too)
147
- if (memberEmail) {
148
- lines.push(`Step 1: Accept the GitHub invitation sent to ${memberEmail}`, ` (if you don't have a GitHub account yet, you'll be guided to create one)`, ` Direct link: ${orgInviteUrl}`, "");
149
- }
150
- else {
151
- lines.push(`Step 1: Accept your GitHub organization invite`, ` Direct link: ${orgInviteUrl}`, ` (if you haven't received one, ask @${payload.invitedBy} to send it)`, "");
152
- }
153
- // Step 2: Install Node.js (platform-specific instructions)
154
- lines.push(`Step 2: Install Node.js (if you don't have it already)`, "", ` Windows (PowerShell, run as Administrator):`, ` winget install OpenJS.NodeJS.LTS`, "", ` Mac (Terminal):`, ` brew install node`, ` (if you don't have brew: https://brew.sh)`, "", ` Or download from: https://nodejs.org`, "");
155
- // Step 3: Single command with token
156
- lines.push(`Step 3: Open your terminal and run this command:`, "", ` npx create-hq --invite ${token}`, "", ` Then follow the prompts to sign in with GitHub and complete setup.`, "", `---`, `Questions? Ask @${payload.invitedBy} or visit https://getindigo.ai/hq`);
157
- return lines.join("\n");
158
- }
159
- /**
160
- * Print the invite details to the console for the admin.
161
- */
162
- export function printInviteSummary(payload, token, _emailSent, memberEmail) {
163
- console.log();
164
- console.log(chalk.bold(" Invite ready!"));
165
- console.log();
166
- console.log(` ${chalk.dim("Team:")} ${chalk.cyan(payload.teamName)}`);
167
- console.log(` ${chalk.dim("Org:")} ${payload.org}`);
168
- if (memberEmail) {
169
- console.log(` ${chalk.dim("Email:")} ${memberEmail}`);
170
- }
171
- console.log();
172
- console.log(chalk.bold(" Invite code (share with the new member):"));
173
- console.log();
174
- console.log(` ${chalk.cyan(token)}`);
175
- console.log();
176
- console.log(chalk.dim(" Full invite message (copy-paste ready):"));
177
- console.log(chalk.dim(" ─".repeat(30)));
178
- const msg = formatInviteMessage(payload, token, memberEmail);
179
- for (const line of msg.split("\n")) {
180
- console.log(chalk.dim(" ") + line);
181
- }
182
- console.log(chalk.dim(" ─".repeat(30)));
183
- console.log();
184
- }
185
- // ─── Mailto helper ──────────────────────────────────────────────────────────
186
- /**
187
- * Build a mailto: URL pre-populated with the invite message.
188
- * Opens in the admin's default email client — they just hit Send.
189
- */
190
- export function buildMailtoUrl(payload, token, recipientEmail) {
191
- const subject = `You're invited to join ${payload.teamName} on HQ`;
192
- const body = formatInviteMessage(payload, token, recipientEmail);
193
- return `mailto:${recipientEmail}?subject=${encodeURIComponent(subject)}&body=${encodeURIComponent(body)}`;
194
- }
195
- /**
196
- * Open the admin's email client with a pre-populated invite email.
197
- */
198
- export function openInviteEmail(payload, token, recipientEmail) {
199
- const url = buildMailtoUrl(payload, token, recipientEmail);
200
- openBrowser(url);
201
- }
202
- /**
203
- * Copy text to the system clipboard. Cross-platform: pbcopy (macOS),
204
- * clip (Windows), xclip/xsel (Linux). Returns true on success.
205
- */
206
- export function copyToClipboard(text) {
207
- try {
208
- const platform = process.platform;
209
- if (platform === "darwin") {
210
- execSync("pbcopy", { input: text });
211
- }
212
- else if (platform === "win32") {
213
- execSync("clip", { input: text });
214
- }
215
- else {
216
- // Try xclip first, fall back to xsel
217
- try {
218
- execSync("xclip -selection clipboard", { input: text });
219
- }
220
- catch {
221
- execSync("xsel --clipboard --input", { input: text });
222
- }
223
- }
224
- return true;
225
- }
226
- catch {
227
- return false;
228
- }
229
- }
230
- //# sourceMappingURL=invite.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"invite.js","sourceRoot":"","sources":["../src/invite.ts"],"names":[],"mappings":"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"}
@@ -1,32 +0,0 @@
1
- /**
2
- * Join-via-invite flow for HQ Teams members.
3
- *
4
- * When a member has an invite token (from an admin), this flow:
5
- * 1. Decodes the token to get team coordinates
6
- * 2. Authenticates via GitHub device flow
7
- * 3. Checks org membership / repo access (waits if invite is pending)
8
- * 4. Clones the team repo into companies/{slug}/
9
- *
10
- * This is the primary path for non-technical users who received an invite.
11
- */
12
- import { type GitHubAuth } from "./auth.js";
13
- export interface JoinByInviteResult {
14
- /** Team slug (companies/{slug}/ directory). */
15
- slug: string;
16
- /** Human-readable team name. */
17
- teamName: string;
18
- /** Local path where the team repo was cloned. */
19
- companyDir: string;
20
- /** GitHub HTML URL for the team repo. */
21
- repoUrl: string;
22
- }
23
- /**
24
- * Run the join-via-invite flow.
25
- *
26
- * @param auth - Authenticated GitHub user (already signed in)
27
- * @param hqRoot - Local HQ root directory (where companies/ lives)
28
- * @param token - The invite token string (hq_...) or raw base64
29
- * @returns - Result on success, null on failure/abort
30
- */
31
- export declare function runJoinByInvite(auth: GitHubAuth, hqRoot: string, token: string): Promise<JoinByInviteResult | null>;
32
- //# sourceMappingURL=join-flow.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"join-flow.d.ts","sourceRoot":"","sources":["../src/join-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAY5C,MAAM,WAAW,kBAAkB;IACjC,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;CACjB;AAwED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAsJpC"}
package/dist/join-flow.js DELETED
@@ -1,315 +0,0 @@
1
- /**
2
- * Join-via-invite flow for HQ Teams members.
3
- *
4
- * When a member has an invite token (from an admin), this flow:
5
- * 1. Decodes the token to get team coordinates
6
- * 2. Authenticates via GitHub device flow
7
- * 3. Checks org membership / repo access (waits if invite is pending)
8
- * 4. Clones the team repo into companies/{slug}/
9
- *
10
- * This is the primary path for non-technical users who received an invite.
11
- */
12
- import * as fs from "fs";
13
- import * as path from "path";
14
- import * as os from "os";
15
- import { execSync } from "child_process";
16
- import { createInterface } from "readline";
17
- import chalk from "chalk";
18
- import { ensureCompanyStructure } from "./company-template.js";
19
- import { stepStatus, success, warn, info, step } from "./ui.js";
20
- import { decodeInviteToken, checkRepoAccess, } from "./invite.js";
21
- import { linkTeamCommands, installTeamCommands } from "./team-setup.js";
22
- // ─── Prompt helpers ─────────────────────────────────────────────────────────
23
- function prompt(question, defaultVal) {
24
- const rl = createInterface({ input: process.stdin, output: process.stdout });
25
- const suffix = defaultVal ? ` (${defaultVal})` : "";
26
- return new Promise((resolve) => {
27
- rl.question(` ? ${question}${suffix} `, (answer) => {
28
- rl.close();
29
- resolve(answer.trim() || defaultVal || "");
30
- });
31
- });
32
- }
33
- function pause(message) {
34
- const rl = createInterface({ input: process.stdin, output: process.stdout });
35
- return new Promise((resolve) => {
36
- rl.question(` ${message}`, () => {
37
- rl.close();
38
- resolve();
39
- });
40
- });
41
- }
42
- // ─── Git helpers (same as team-setup.ts / admin-onboarding.ts) ──────────────
43
- function runGitWithToken(args, cwd, auth) {
44
- const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "create-hq-git-"));
45
- const isWindows = process.platform === "win32";
46
- const askpassPath = path.join(tmpDir, isWindows ? "askpass.cmd" : "askpass.sh");
47
- try {
48
- if (isWindows) {
49
- fs.writeFileSync(askpassPath, `@echo off\nif "%~1"=="" (echo %GIT_TOKEN%) else (echo %GIT_TOKEN%)\n`, "utf-8");
50
- }
51
- else {
52
- fs.writeFileSync(askpassPath, `#!/bin/sh\necho "$GIT_TOKEN"\n`, "utf-8");
53
- fs.chmodSync(askpassPath, 0o700);
54
- }
55
- execSync(`git -c credential.helper= ${args.join(" ")}`, {
56
- cwd,
57
- stdio: "pipe",
58
- env: {
59
- ...process.env,
60
- GIT_TOKEN: auth.access_token,
61
- GIT_ASKPASS: askpassPath,
62
- GIT_TERMINAL_PROMPT: "0",
63
- GCM_INTERACTIVE: "never",
64
- },
65
- });
66
- }
67
- finally {
68
- try {
69
- fs.rmSync(tmpDir, { recursive: true, force: true });
70
- }
71
- catch {
72
- // ignore
73
- }
74
- }
75
- }
76
- function tokenAuthUrl(cloneUrl) {
77
- const u = new URL(cloneUrl);
78
- u.username = "x-access-token";
79
- return u.toString();
80
- }
81
- // ─── Main flow ──────────────────────────────────────────────────────────────
82
- /**
83
- * Run the join-via-invite flow.
84
- *
85
- * @param auth - Authenticated GitHub user (already signed in)
86
- * @param hqRoot - Local HQ root directory (where companies/ lives)
87
- * @param token - The invite token string (hq_...) or raw base64
88
- * @returns - Result on success, null on failure/abort
89
- */
90
- export async function runJoinByInvite(auth, hqRoot, token) {
91
- // 1. Decode token
92
- const payload = decodeInviteToken(token);
93
- if (!payload) {
94
- warn("Invalid invite code. Check that you copied it correctly and try again.");
95
- return null;
96
- }
97
- console.log();
98
- console.log(chalk.bold(" Joining a team"));
99
- console.log();
100
- console.log(` ${chalk.dim("Team:")} ${chalk.cyan(payload.teamName)}`);
101
- console.log(` ${chalk.dim("Org:")} ${payload.org}`);
102
- console.log(` ${chalk.dim("Invited by:")} @${payload.invitedBy}`);
103
- console.log();
104
- // 2. Check repo access (proves org membership + repo visibility)
105
- const accessLabel = `Checking access to ${payload.org}/${payload.repo}`;
106
- stepStatus(accessLabel, "running");
107
- let hasAccess = await checkRepoAccess(auth, payload.org, payload.repo);
108
- if (!hasAccess) {
109
- stepStatus(accessLabel, "failed");
110
- console.log();
111
- // Guide the user to accept the org invite
112
- info("You don't have access to this team's repository yet.");
113
- console.log();
114
- step("Check your email for a GitHub organization invite from " + chalk.cyan(payload.org));
115
- step("Accept the invite, then come back here.");
116
- console.log();
117
- // Give them up to 3 chances to retry
118
- for (let attempt = 1; attempt <= 3; attempt++) {
119
- await pause(`Press Enter after accepting the invite (attempt ${attempt}/3)... `);
120
- stepStatus(`Re-checking access (attempt ${attempt})`, "running");
121
- hasAccess = await checkRepoAccess(auth, payload.org, payload.repo);
122
- if (hasAccess) {
123
- stepStatus(`Re-checking access (attempt ${attempt})`, "done");
124
- break;
125
- }
126
- else {
127
- stepStatus(`Re-checking access (attempt ${attempt})`, "failed");
128
- if (attempt < 3) {
129
- console.log();
130
- info("Still no access. Make sure you:");
131
- step(`Accepted the org invite from ${payload.org} (check email from GitHub)`);
132
- step("Are signed in to GitHub with the same account you accepted the invite on");
133
- console.log();
134
- }
135
- }
136
- }
137
- if (!hasAccess) {
138
- console.log();
139
- warn("Could not access the team repository after 3 attempts.");
140
- info(`Your GitHub username is @${auth.login}`);
141
- info(`Ask @${payload.invitedBy} to add @${auth.login} to the ${payload.org} organization.`);
142
- info("Then run create-hq again with the same invite code.");
143
- return null;
144
- }
145
- }
146
- else {
147
- stepStatus(accessLabel, "done");
148
- }
149
- // 3. Clone the repo into companies/{slug}/
150
- const companiesDir = path.join(hqRoot, "companies");
151
- if (!fs.existsSync(companiesDir)) {
152
- fs.mkdirSync(companiesDir, { recursive: true });
153
- }
154
- const companyDir = path.join(companiesDir, payload.slug);
155
- if (fs.existsSync(companyDir) && fs.readdirSync(companyDir).length > 0) {
156
- // Company directory already exists — just ensure the git remote is set
157
- // so the user can sync later from within Claude. Don't clone over their files.
158
- const remoteLabel = `Configuring remote for existing companies/${payload.slug}`;
159
- stepStatus(remoteLabel, "running");
160
- try {
161
- ensureGitRemote(companyDir, payload.cloneUrl);
162
- stepStatus(remoteLabel, "done");
163
- info(`companies/${payload.slug}/ already exists — configured git remote (sync later with /team-sync)`);
164
- }
165
- catch {
166
- stepStatus(remoteLabel, "done");
167
- info(`companies/${payload.slug}/ already exists — remote already configured`);
168
- }
169
- }
170
- else {
171
- const cloneLabel = `Cloning ${payload.teamName} into companies/${payload.slug}`;
172
- stepStatus(cloneLabel, "running");
173
- try {
174
- const remoteUrl = tokenAuthUrl(payload.cloneUrl);
175
- runGitWithToken(["clone", `"${remoteUrl}"`, `"${companyDir}"`], companiesDir, auth);
176
- // Strip the token from the stored remote URL
177
- execSync(`git remote set-url origin "${payload.cloneUrl}"`, {
178
- cwd: companyDir,
179
- stdio: "pipe",
180
- });
181
- // Ensure standard company subdirectories exist
182
- ensureCompanyStructure(companyDir);
183
- stepStatus(cloneLabel, "done");
184
- }
185
- catch (err) {
186
- stepStatus(cloneLabel, "failed");
187
- const message = err instanceof Error ? err.message : String(err);
188
- warn(`Could not clone team repo: ${message}`);
189
- // Provide actionable guidance
190
- console.log();
191
- info("This usually means the repository doesn't exist or your access isn't set up yet.");
192
- info(`Ask @${payload.invitedBy} to verify the repo exists at: https://github.com/${payload.org}/${payload.repo}`);
193
- return null;
194
- }
195
- }
196
- // Register the company in manifest.yaml so HQ routing (search, /startwork, workers) can find it
197
- registerInManifest(hqRoot, payload);
198
- // Install bundled team commands (invite, sync, promote)
199
- const installed = installTeamCommands(hqRoot);
200
- if (installed.length > 0) {
201
- info(`Installed ${installed.length} team command${installed.length === 1 ? "" : "s"}: ${installed.join(", ")}`);
202
- }
203
- // Link team-distributed commands as slash commands
204
- const symlinks = linkTeamCommands(hqRoot, payload.slug);
205
- if (symlinks.linked.length > 0) {
206
- info(`Linked ${symlinks.linked.length} team command${symlinks.linked.length === 1 ? "" : "s"}`);
207
- }
208
- const repoUrl = `https://github.com/${payload.org}/${payload.repo}`;
209
- console.log();
210
- success(`Joined ${payload.teamName}!`);
211
- info(`Team workspace: companies/${payload.slug}/`);
212
- return {
213
- slug: payload.slug,
214
- teamName: payload.teamName,
215
- companyDir,
216
- repoUrl,
217
- };
218
- }
219
- // ─── Manifest registration ─────────────────────────────────────────────────
220
- /**
221
- * Register a joined team in companies/manifest.yaml so HQ's routing system
222
- * (search scoping, /startwork, workers, /run-project) can discover it.
223
- *
224
- * Appends a minimal entry if the slug isn't already present. Uses string
225
- * manipulation to avoid adding a YAML parser dependency to create-hq.
226
- */
227
- function registerInManifest(hqRoot, payload) {
228
- const manifestPath = path.join(hqRoot, "companies", "manifest.yaml");
229
- // If manifest doesn't exist yet (fresh HQ), create a minimal one
230
- if (!fs.existsSync(manifestPath)) {
231
- const initial = [
232
- "# Companies Manifest",
233
- '# Maps each company to its repos, workers, knowledge, deploy targets, and infrastructure.',
234
- "",
235
- 'version: "1.1"',
236
- `updated: "${new Date().toISOString().slice(0, 10)}"`,
237
- "",
238
- "companies:",
239
- ...formatManifestEntry(payload),
240
- "",
241
- ].join("\n");
242
- fs.writeFileSync(manifestPath, initial, "utf-8");
243
- return;
244
- }
245
- // Check if slug is already registered
246
- const existing = fs.readFileSync(manifestPath, "utf-8");
247
- const slugPattern = new RegExp(`^ ${escapeRegex(payload.slug)}:`, "m");
248
- if (slugPattern.test(existing)) {
249
- return; // Already in manifest
250
- }
251
- // Append the new entry at the end of the companies block
252
- const entry = formatManifestEntry(payload).join("\n");
253
- const updated = existing.trimEnd() + "\n\n" + entry + "\n";
254
- fs.writeFileSync(updated.includes("updated:") ? manifestPath : manifestPath, updated, "utf-8");
255
- // Update the "updated" date
256
- const dateUpdated = updated.replace(/^updated: ".*"$/m, `updated: "${new Date().toISOString().slice(0, 10)}"`);
257
- fs.writeFileSync(manifestPath, dateUpdated, "utf-8");
258
- }
259
- function formatManifestEntry(payload) {
260
- return [
261
- ` ${payload.slug}:`,
262
- ` github_org: ${payload.org}`,
263
- ` repos: []`,
264
- ` settings: []`,
265
- ` workers: []`,
266
- ` knowledge: companies/${payload.slug}/knowledge/`,
267
- ` deploy: []`,
268
- ` vercel_projects: []`,
269
- ` qmd_collections:`,
270
- ` - ${payload.slug}`,
271
- ` services: []`,
272
- ];
273
- }
274
- function escapeRegex(str) {
275
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
276
- }
277
- // ─── Git remote helper ─────────────────────────────────────────────────────
278
- /**
279
- * Ensure an existing directory has a git remote pointing to the team repo.
280
- * If it's not a git repo, initializes one. If 'origin' exists with a different
281
- * URL, adds 'team' as the remote name instead.
282
- */
283
- function ensureGitRemote(dir, cloneUrl) {
284
- // Initialize git if not already a repo
285
- const gitDir = path.join(dir, ".git");
286
- if (!fs.existsSync(gitDir)) {
287
- execSync("git init", { cwd: dir, stdio: "pipe" });
288
- }
289
- // Check existing remotes
290
- let existingOrigin = null;
291
- try {
292
- existingOrigin = execSync("git remote get-url origin", { cwd: dir, stdio: "pipe" })
293
- .toString()
294
- .trim();
295
- }
296
- catch {
297
- // No origin remote
298
- }
299
- if (!existingOrigin) {
300
- // No origin — add it
301
- execSync(`git remote add origin "${cloneUrl}"`, { cwd: dir, stdio: "pipe" });
302
- }
303
- else if (existingOrigin !== cloneUrl) {
304
- // Origin exists but points elsewhere — add as 'team' remote
305
- try {
306
- execSync(`git remote add team "${cloneUrl}"`, { cwd: dir, stdio: "pipe" });
307
- }
308
- catch {
309
- // 'team' remote might already exist
310
- execSync(`git remote set-url team "${cloneUrl}"`, { cwd: dir, stdio: "pipe" });
311
- }
312
- }
313
- // If origin already matches cloneUrl, nothing to do
314
- }
315
- //# sourceMappingURL=join-flow.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"join-flow.js","sourceRoot":"","sources":["../src/join-flow.ts"],"names":[],"mappings":"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"}