@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.
- package/README.md +4 -0
- package/bin/sd.mjs +28 -2
- 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(`
|
|
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 === "
|
|
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);
|