@floomhq/floom 1.0.20 → 1.0.21

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 CHANGED
@@ -22,7 +22,7 @@ The package is designed for `npx -y @floomhq/floom ...`. Global installs expose
22
22
 
23
23
  ## Commands
24
24
 
25
- - `npx -y @floomhq/floom login` — sign in with Google. New accounts are created on first login. Token stored at `~/.floom/config.json`.
25
+ - `npx -y @floomhq/floom login` — sign in with Google. Use `--provider github` for GitHub. New accounts are created on first login. Token stored at `~/.floom/config.json`.
26
26
  - `npx -y @floomhq/floom init [path]` — create a starter skill folder at `<path>/SKILL.md`. Passing an existing-style `file.md` path still creates that Markdown file.
27
27
  - `npx -y @floomhq/floom publish <path>` — upload a skill folder or Markdown file. Folder packages use `<slug>/SKILL.md` plus optional `references/`, `examples/`, `scripts/`, and `assets/`. Optional `--public` / `--private` / `--unlisted`, `--type knowledge|instruction|workflow|skill`, `--installs-as <target>`, and `--skill-version <label>`.
28
28
  - `npx -y @floomhq/floom share <slug>` — email-share one of your skills. Optional `--add <email>`, `--remove <email>`, and `--list`.
package/dist/cli.js CHANGED
@@ -162,6 +162,13 @@ Diagnose auth, API reachability, PATH collisions, MCP setup, and local skills fo
162
162
  ${c.bold("Flags")}
163
163
  ${c.cyan("--target")} ${c.dim("claude|codex")} Check Claude Code or Codex paths. Default: claude.
164
164
  ${c.cyan("--json")} Print structured checks for scripts.
165
+ `,
166
+ login: `${c.bold("Usage:")} ${c.cyan(`${CLI_COMMAND} login`)} ${c.dim("[flags]")}
167
+
168
+ Sign in through browser OAuth.
169
+
170
+ ${c.bold("Flags")}
171
+ ${c.cyan("--provider")} ${c.dim("google|github")} OAuth provider. Default: google.
165
172
  `,
166
173
  publish: `${c.bold("Usage:")} ${c.cyan(`${CLI_COMMAND} publish`)} ${c.dim("<path> [flags]")}
167
174
 
@@ -255,6 +262,23 @@ function readFlagValue(argv, index, flag) {
255
262
  throw new FloomError(`Missing value for ${flag}.`);
256
263
  return { value, nextIndex: index + 1 };
257
264
  }
265
+ function parseLoginArgs(argv) {
266
+ let provider = "google";
267
+ for (let i = 0; i < argv.length; i += 1) {
268
+ const a = argv[i] ?? "";
269
+ if (a === "--provider" || a.startsWith("--provider=")) {
270
+ const { value, nextIndex } = readFlagValue(argv, i, "--provider");
271
+ if (value !== "google" && value !== "github") {
272
+ throw new FloomError("Invalid --provider.", "Use google or github.");
273
+ }
274
+ provider = value;
275
+ i = nextIndex;
276
+ continue;
277
+ }
278
+ throw new FloomError(`Unknown flag or argument: ${a}`, `Try \`${CLI_COMMAND} login --provider github\`.`);
279
+ }
280
+ return { provider };
281
+ }
258
282
  function parseFlags(argv) {
259
283
  const out = { visibility: "unlisted", update: false, rest: [] };
260
284
  let visibilityFlag = null;
@@ -852,8 +876,7 @@ async function main() {
852
876
  process.stdout.write(`${CLI_VERSION}\n`);
853
877
  return;
854
878
  case "login":
855
- rejectArgs(rest, `Try \`${CLI_COMMAND} login\`.`);
856
- await login();
879
+ await login(parseLoginArgs(rest).provider);
857
880
  return;
858
881
  case "logout":
859
882
  rejectArgs(rest, `Try \`${CLI_COMMAND} logout\`.`);
package/dist/login.js CHANGED
@@ -8,18 +8,19 @@ import { c, header, symbols } from "./ui.js";
8
8
  import { FloomError, friendlyHttp, friendlyNetwork } from "./errors.js";
9
9
  const DEFAULT_PORT = 7456;
10
10
  const TIMEOUT_MS = 5 * 60 * 1000;
11
- export async function login() {
11
+ export async function login(provider = "google") {
12
12
  const apiUrl = getApiUrl();
13
13
  const port = await pickPort();
14
+ const providerLabel = provider === "github" ? "GitHub" : "Google";
14
15
  process.stdout.write(header());
15
- process.stdout.write(`${symbols.arrow} Opening browser to sign in with Google...\n\n`);
16
+ process.stdout.write(`${symbols.arrow} Opening browser to sign in with ${providerLabel}...\n\n`);
16
17
  const spinner = ora({
17
18
  text: c.dim("Waiting for sign-in to complete..."),
18
19
  color: "yellow",
19
20
  }).start();
20
21
  let tokens;
21
22
  try {
22
- tokens = await waitForCallback(port);
23
+ tokens = await waitForCallback(port, provider);
23
24
  }
24
25
  catch (err) {
25
26
  spinner.stop();
@@ -90,7 +91,7 @@ function reserveEphemeralPort() {
90
91
  });
91
92
  });
92
93
  }
93
- function waitForCallback(port) {
94
+ function waitForCallback(port, provider) {
94
95
  return new Promise((resolve, reject) => {
95
96
  const apiUrl = getApiUrl();
96
97
  const state = randomBytes(32).toString("base64url");
@@ -172,7 +173,7 @@ function waitForCallback(port) {
172
173
  reject(new FloomError(`Local auth server failed on port ${port}.`, `Is port ${port} already in use? (${err.message})`));
173
174
  });
174
175
  server.listen(port, "127.0.0.1", () => {
175
- const target = `${apiUrl}/auth/cli?port=${port}&state=${encodeURIComponent(state)}`;
176
+ const target = `${apiUrl}/auth/cli?port=${port}&provider=${provider}&state=${encodeURIComponent(state)}`;
176
177
  open(target).catch((e) => {
177
178
  const msg = e instanceof Error ? e.message : String(e);
178
179
  process.stdout.write(c.yellow(`Could not auto-open browser (${msg}).\n`) +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floomhq/floom",
3
- "version": "1.0.20",
3
+ "version": "1.0.21",
4
4
  "description": "Sync AI skills across agents and machines.",
5
5
  "license": "MIT",
6
6
  "type": "module",