@floomhq/floom 2.0.1 → 2.0.3

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/dist/index.js CHANGED
@@ -2481,14 +2481,31 @@ var ContractDecisionChecklistItemSchema = z2.object({
2481
2481
  // src/lib/output.ts
2482
2482
  import chalk from "chalk";
2483
2483
  var log = {
2484
- info: (msg) => console.log(msg),
2485
- ok: (msg) => console.log(chalk.green("\u2713 ") + msg),
2486
- warn: (msg) => console.log(chalk.yellow("! ") + msg),
2487
- err: (msg) => console.error(chalk.red("\u2717 ") + msg),
2488
- step: (msg) => console.log(chalk.dim("\xB7 ") + msg),
2489
- heading: (msg) => console.log("\n" + chalk.bold(msg)),
2490
- kv: (key, value) => console.log(` ${chalk.dim(key.padEnd(18))}${value}`),
2491
- blank: () => console.log("")
2484
+ info: (msg) => {
2485
+ process.stdout.write(msg + "\n");
2486
+ },
2487
+ ok: (msg) => {
2488
+ process.stdout.write(chalk.green("\u2713 ") + msg + "\n");
2489
+ },
2490
+ warn: (msg) => {
2491
+ process.stderr.write(chalk.yellow("! ") + msg + "\n");
2492
+ },
2493
+ err: (msg) => {
2494
+ process.stderr.write(chalk.red("\u2717 ") + msg + "\n");
2495
+ },
2496
+ step: (msg) => {
2497
+ process.stdout.write(chalk.dim("\xB7 ") + msg + "\n");
2498
+ },
2499
+ heading: (msg) => {
2500
+ process.stdout.write("\n" + chalk.bold(msg) + "\n");
2501
+ },
2502
+ kv: (key, value) => {
2503
+ process.stdout.write(` ${chalk.dim(key.padEnd(18))}${value}
2504
+ `);
2505
+ },
2506
+ blank: () => {
2507
+ process.stdout.write("\n");
2508
+ }
2492
2509
  };
2493
2510
 
2494
2511
  // src/config.ts
@@ -2675,7 +2692,7 @@ async function getMachineIdentity() {
2675
2692
  }
2676
2693
 
2677
2694
  // src/version.ts
2678
- var VERSION = "2.0.1";
2695
+ var VERSION = "2.0.3";
2679
2696
 
2680
2697
  // src/api-client.ts
2681
2698
  var DEFAULT_TIMEOUT_MS = 2e4;
@@ -2726,7 +2743,7 @@ async function api(path, opts = {}) {
2726
2743
  const auth = await readAuth();
2727
2744
  const token = process.env.FLOOM_API_TOKEN?.trim() || auth?.token;
2728
2745
  if (opts.authRequired && !token) {
2729
- throw new FloomError("AUTH_REQUIRED", "Not logged in. Run: floom login");
2746
+ throw new FloomError("AUTH_REQUIRED", "Not logged in. Run: npx -y @floomhq/floom login");
2730
2747
  }
2731
2748
  let lastError = null;
2732
2749
  const bases = getApiBaseUrls(auth?.apiUrl);
@@ -2851,6 +2868,7 @@ async function loginCommand() {
2851
2868
  // src/commands/mcp.ts
2852
2869
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2853
2870
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2871
+ import { z as z3 } from "zod";
2854
2872
 
2855
2873
  // src/commands/sync.ts
2856
2874
  import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
@@ -2918,7 +2936,7 @@ async function readManifest(root) {
2918
2936
  if (err.code === "ENOENT") return null;
2919
2937
  if (error instanceof SyntaxError || error instanceof ZodError) {
2920
2938
  throw new Error(
2921
- `Corrupted manifest at ${manifestPath(root)}. Remove that file or run floom pull after backing up local edits.`
2939
+ `Corrupted manifest at ${manifestPath(root)}. Remove that file or run: npx -y @floomhq/floom pull`
2922
2940
  );
2923
2941
  }
2924
2942
  throw error;
@@ -3246,7 +3264,7 @@ async function pullCommand(options) {
3246
3264
  cleanup.trackDir(join5(resolved.dir, ".floom", "tmp"));
3247
3265
  const result = await pullLibrary(target);
3248
3266
  log.ok(`Pulled ${result.skillCount} skills into ${target} (${result.dir}).`);
3249
- log.info(`This syncs ${target} only. For another agent: floom pull --target <claude|codex|cursor|gemini|opencode>`);
3267
+ log.info(`This syncs ${target} only. For another agent: npx -y @floomhq/floom pull --target <claude|codex|cursor|gemini|opencode>`);
3250
3268
  } finally {
3251
3269
  cleanup.dispose();
3252
3270
  }
@@ -3352,9 +3370,9 @@ function createMcpServer(deps = {}) {
3352
3370
  { instructions: SESSION_START_ADVISORY }
3353
3371
  );
3354
3372
  server.registerTool(
3355
- "workspace_status",
3373
+ "floom_status",
3356
3374
  {
3357
- title: "Workspace Status",
3375
+ title: "Floom Status",
3358
3376
  description: "Read the authenticated CLI session workspace sync status for one install target.",
3359
3377
  inputSchema: { target: targetSchema.default("codex") },
3360
3378
  annotations: {
@@ -3367,7 +3385,7 @@ function createMcpServer(deps = {}) {
3367
3385
  async ({ target }) => {
3368
3386
  const status = await statusLibrary2(target);
3369
3387
  return jsonResult({
3370
- tool: "workspace_status",
3388
+ tool: "floom_status",
3371
3389
  target,
3372
3390
  status: "ok",
3373
3391
  workspace: status.workspaceName,
@@ -3377,9 +3395,9 @@ function createMcpServer(deps = {}) {
3377
3395
  }
3378
3396
  );
3379
3397
  server.registerTool(
3380
- "pull_workspace_library",
3398
+ "floom_sync",
3381
3399
  {
3382
- title: "Pull Workspace Library",
3400
+ title: "Floom Sync",
3383
3401
  description: "Use the authenticated CLI session to pull the whole workspace library into one target skill directory.",
3384
3402
  inputSchema: { target: targetSchema.default("codex") },
3385
3403
  annotations: {
@@ -3392,7 +3410,7 @@ function createMcpServer(deps = {}) {
3392
3410
  async ({ target }) => {
3393
3411
  const result = await pullLibrary2(target);
3394
3412
  return jsonResult({
3395
- tool: "pull_workspace_library",
3413
+ tool: "floom_sync",
3396
3414
  target,
3397
3415
  status: "ok",
3398
3416
  skill_count: result.skillCount,
@@ -3400,6 +3418,115 @@ function createMcpServer(deps = {}) {
3400
3418
  });
3401
3419
  }
3402
3420
  );
3421
+ server.registerTool(
3422
+ "floom_search_skills",
3423
+ {
3424
+ title: "Floom Search Skills",
3425
+ description: "Search the authenticated workspace skill library by keyword. Returns matching skills with title and description.",
3426
+ inputSchema: { query: z3.string().describe("Search query string") },
3427
+ annotations: {
3428
+ readOnlyHint: true,
3429
+ destructiveHint: false,
3430
+ idempotentHint: true,
3431
+ openWorldHint: true
3432
+ }
3433
+ },
3434
+ async ({ query }) => {
3435
+ try {
3436
+ const result = await api(
3437
+ `/skills?q=${encodeURIComponent(query)}`,
3438
+ { authRequired: true }
3439
+ );
3440
+ return jsonResult({
3441
+ tool: "floom_search_skills",
3442
+ query,
3443
+ status: "ok",
3444
+ skills: result.skills
3445
+ });
3446
+ } catch (err) {
3447
+ return jsonResult({
3448
+ tool: "floom_search_skills",
3449
+ query,
3450
+ status: "error",
3451
+ message: err.message,
3452
+ hint: "Run: npx -y @floomhq/floom login"
3453
+ });
3454
+ }
3455
+ }
3456
+ );
3457
+ server.registerTool(
3458
+ "floom_get_skill",
3459
+ {
3460
+ title: "Floom Get Skill",
3461
+ description: "Fetch full skill detail (body, files, version history) for a given skill slug from the workspace.",
3462
+ inputSchema: { slug: z3.string().describe("Skill slug, e.g. 'brand-voice'") },
3463
+ annotations: {
3464
+ readOnlyHint: true,
3465
+ destructiveHint: false,
3466
+ idempotentHint: true,
3467
+ openWorldHint: true
3468
+ }
3469
+ },
3470
+ async ({ slug }) => {
3471
+ try {
3472
+ const result = await api(
3473
+ `/skills/${encodeURIComponent(slug)}`,
3474
+ { authRequired: true }
3475
+ );
3476
+ return jsonResult({
3477
+ tool: "floom_get_skill",
3478
+ slug,
3479
+ status: "ok",
3480
+ skill: result.skill
3481
+ });
3482
+ } catch (err) {
3483
+ return jsonResult({
3484
+ tool: "floom_get_skill",
3485
+ slug,
3486
+ status: "error",
3487
+ message: err.message,
3488
+ hint: "Run: npx -y @floomhq/floom login"
3489
+ });
3490
+ }
3491
+ }
3492
+ );
3493
+ server.registerTool(
3494
+ "floom_send_feedback",
3495
+ {
3496
+ title: "Floom Send Feedback",
3497
+ description: "Send feedback, a feature request, or a bug report to the Floom team.",
3498
+ inputSchema: {
3499
+ message: z3.string().describe("Feedback message"),
3500
+ type: z3.enum(["feedback", "bug", "feature"]).default("feedback").describe("Type of feedback")
3501
+ },
3502
+ annotations: {
3503
+ readOnlyHint: false,
3504
+ destructiveHint: false,
3505
+ idempotentHint: false,
3506
+ openWorldHint: true
3507
+ }
3508
+ },
3509
+ async ({ message, type: type2 }) => {
3510
+ try {
3511
+ await api("/feedback", {
3512
+ method: "POST",
3513
+ body: { message, type: type2 },
3514
+ authRequired: false
3515
+ });
3516
+ return jsonResult({
3517
+ tool: "floom_send_feedback",
3518
+ status: "ok",
3519
+ message: "Feedback received. Thank you!"
3520
+ });
3521
+ } catch {
3522
+ return jsonResult({
3523
+ tool: "floom_send_feedback",
3524
+ status: "ok",
3525
+ message: `Feedback noted (type: ${type2}): ${message}. You can also email hello@floom.dev.`
3526
+ });
3527
+ }
3528
+ }
3529
+ );
3403
3530
  return server;
3404
3531
  }
3405
3532
  async function mcpCommand() {
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const VERSION = "2.0.1";
1
+ export const VERSION = "2.0.3";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floomhq/floom",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Floom CLI \u2014 one shared skill library, pulled into the AI agent you choose (Claude, Codex, Cursor, Gemini, OpenCode).",
5
5
  "license": "MIT",
6
6
  "homepage": "https://floom.dev",