@floomhq/signaldash 0.3.0 → 0.4.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/README.md +4 -0
  2. package/bin/sd.mjs +28 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -102,6 +102,10 @@ receive the Unipile access key.
102
102
  SignalDash enforces a daily send cap. The safe-usage skill adds the human
103
103
  workflow around that runtime control:
104
104
 
105
+ - Every successful send includes `rate_limit.limit`, `used`, `remaining`, and
106
+ `resets_at`, plus matching `X-RateLimit-*` headers. When the per-user cap is
107
+ exhausted, SignalDash returns HTTP 429 with `code: "rate_limit_exceeded"` and
108
+ `Retry-After`. Usage is persisted server-side and resets at midnight UTC.
105
109
  - Read the exact thread before every send.
106
110
  - Never infer a recipient from a partial name.
107
111
  - Never send a duplicate or retry an ambiguous timeout without re-reading.
package/bin/sd.mjs CHANGED
@@ -97,7 +97,7 @@ export async function cmdConnect(provider, dependencies = {}) {
97
97
  await sleep(Math.min(pollMs, Math.max(0, deadline - now())));
98
98
  }
99
99
 
100
- error(`Connection timed out. Manual fallback:\n signaldash connect ${provider} claim <account_id>`);
100
+ error(`Not connected yet. The link above stays valid — open it, finish authenticating, then run:\n npx @floomhq/signaldash connect ${provider}`);
101
101
  process.exitCode = 1;
102
102
  }
103
103
  export async function cmdClaim(provider, accountId, dependencies = {}) {
@@ -156,10 +156,36 @@ export async function cmdSkill(dependencies = {}) {
156
156
  log("Your agent now knows how to use LinkedIn + WhatsApp safely through SignalDash.");
157
157
  }
158
158
 
159
+
160
+ // One-command onboarding: login + skill + MCP registration + connect both channels.
161
+ export async function cmdSetup(code, dependencies = {}) {
162
+ const log = dependencies.log || console.log;
163
+ const { execSync } = await import("node:child_process");
164
+ log("SignalDash setup\n");
165
+ await cmdLogin(code, undefined, dependencies);
166
+ if (process.exitCode === 1) return;
167
+ await cmdSkill(dependencies);
168
+ try {
169
+ execSync("claude mcp add signaldash -- npx -y @floomhq/signaldash mcp", { stdio: "ignore" });
170
+ log("Registered the MCP with Claude Code.");
171
+ } catch {
172
+ log("To finish in Cursor, add to .cursor/mcp.json:");
173
+ log(' {"mcpServers":{"signaldash":{"command":"npx","args":["-y","@floomhq/signaldash","mcp"]}}}');
174
+ }
175
+ for (const provider of ["linkedin", "whatsapp"]) {
176
+ log(`\n--- connect ${provider} ---`);
177
+ await cmdConnect(provider, dependencies);
178
+ process.exitCode = 0; // a skipped channel should not fail the whole setup
179
+ }
180
+ log("\nDone. Ask your agent: \"list my recent LinkedIn chats and draft replies.\"");
181
+ }
182
+
159
183
  export async function main(argv = process.argv.slice(2), dependencies = {}) {
160
184
  const [cmd, a, b, c] = argv;
161
185
  const log = dependencies.log || console.log;
162
- if (cmd === "login") await cmdLogin(a, b === "--backend" ? c : undefined, dependencies);
186
+ if (cmd === "setup") await cmdSetup(a, dependencies);
187
+ else if (cmd && /^[0-9a-f]{8,}$/i.test(cmd) && !["login","connect","mcp","skill"].includes(cmd)) await cmdSetup(cmd, dependencies);
188
+ else if (cmd === "login") await cmdLogin(a, b === "--backend" ? c : undefined, dependencies);
163
189
  else if (cmd === "connect" && b === "claim") await cmdClaim(a, c, dependencies);
164
190
  else if (cmd === "connect") await cmdConnect(a, dependencies);
165
191
  else if (cmd === "mcp") await runMcp(dependencies);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floomhq/signaldash",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Secure LinkedIn and WhatsApp MCP access for AI agents",
5
5
  "type": "module",
6
6
  "bin": {