@floomhq/signaldash 0.33.2 → 0.35.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 CHANGED
@@ -102,7 +102,7 @@ setup installs both from the same pinned npm package
102
102
  the human chose to execute:
103
103
 
104
104
  ```bash
105
- npx -y @floomhq/signaldash@0.33.2 <invite-code>
105
+ npx -y @floomhq/signaldash@0.35.0 <invite-code>
106
106
  ```
107
107
 
108
108
  Run that command in a terminal, not in an agent chat. Do not ask an agent to
@@ -121,6 +121,12 @@ SignalDash exposes:
121
121
 
122
122
  - `sd_version()`
123
123
  - `sd_secretary_latest(limit?, continuation?, ack_token?)`
124
+ - `sd_secretary_push_set(enabled, confirm)`
125
+ - `sd_inspiration_list(limit?, status?, content_kind?)`
126
+ - `sd_inspiration_status(id, status, resulting_post_urn?, confirm)`
127
+ - `sd_inspiration_import(source, source_author?, federico_note?, purpose?, content_kind?, credit_required?, credit_note?, format_description?)`
128
+ - `sd_inspiration_channel_configure(chat_id, provider_id, chat_name, confirm)`
129
+ - `sd_inspiration_channel_set(capture_enabled, confirm)`
124
130
  - `sd_secretary_approve(disposition_id, payload_hash, confirm)`
125
131
  - `sd_secretary_reject(disposition_id, confirm)`
126
132
  - `li_list_chats`
@@ -181,6 +187,16 @@ SignalDash exposes:
181
187
  Every operation runs through the hosted SignalDash backend. Agents never
182
188
  receive the Unipile access key.
183
189
 
190
+ The hourly Secretary push reuses the existing LinkedIn collector cycle and
191
+ adds no second inbox poll. It sends only when a new tracked-thread reply,
192
+ own-post comment or reaction, or approval-ready draft was stored after push was
193
+ enabled. No change means no WhatsApp provider call and no notification. Every
194
+ push resolves the exact configured Secretary group from the connected account
195
+ and live chat list, reads before sending, and requires an exact one-message
196
+ readback. `sd_secretary_push_set` is the database kill switch; enabling starts
197
+ from that instant so old rows do not create a backlog. The self-chat is never a
198
+ fallback.
199
+
184
200
  `li_reply_to_comment` acts only on an inbound comment on the authenticated
185
201
  sender's own post. A preceding `li_post_comments` read records an exact
186
202
  per-comment watermark. Immediately before the write, SignalDash re-proves the
package/bin/sd.mjs CHANGED
@@ -337,6 +337,100 @@ const TOOLS = [
337
337
  additionalProperties: false,
338
338
  },
339
339
  },
340
+ {
341
+ name: "sd_secretary_push_set",
342
+ path: "/sd/secretary/push/set",
343
+ description: "Enable or disable hourly change-only Secretary notifications to the exact verified WhatsApp group. Enabling re-proves the live WhatsApp account and group and starts from that instant, so old signals do not create a backlog. Disabling is a database kill switch and needs no deploy or restart.",
344
+ inputSchema: {
345
+ type: "object",
346
+ properties: {
347
+ enabled: { type: "boolean" },
348
+ confirm: { type: "boolean", const: true },
349
+ },
350
+ required: ["enabled", "confirm"],
351
+ additionalProperties: false,
352
+ },
353
+ },
354
+ {
355
+ name: "sd_inspiration_list",
356
+ path: "/sd/inspiration/list",
357
+ description: "Read Federico's stored inspiration formats, ranked by source engagement at capture. Defaults to status offen and post formats, so genutzt entries and business ideas are never proposed accidentally. Every row carries source author, URL, exact text, credit requirement, and draft provenance. Makes zero provider requests.",
358
+ inputSchema: {
359
+ type: "object",
360
+ properties: {
361
+ limit: { type: "integer", minimum: 1, maximum: 100, default: 20 },
362
+ status: { type: "string", enum: ["offen", "in arbeit", "genutzt", "alle"], default: "offen" },
363
+ content_kind: { type: "string", enum: ["post_format", "business_idea", "all"], default: "post_format" },
364
+ },
365
+ additionalProperties: false,
366
+ },
367
+ },
368
+ {
369
+ name: "sd_inspiration_status",
370
+ path: "/sd/inspiration/status",
371
+ description: "Move one inspiration entry to offen, in arbeit, or genutzt. Genutzt is terminal and requires the exact resulting LinkedIn post URN, preventing the format from ever being proposed again.",
372
+ inputSchema: {
373
+ type: "object",
374
+ properties: {
375
+ id: { type: "string", minLength: 1, maxLength: 200 },
376
+ status: { type: "string", enum: ["offen", "in arbeit", "genutzt"] },
377
+ resulting_post_urn: { type: "string", pattern: "^urn:li:(activity|ugcPost|share):[0-9]+$" },
378
+ confirm: { type: "boolean", const: true },
379
+ },
380
+ required: ["id", "status", "confirm"],
381
+ additionalProperties: false,
382
+ },
383
+ },
384
+ {
385
+ name: "sd_inspiration_import",
386
+ path: "/sd/inspiration/import",
387
+ description: "Import one exact LinkedIn post URL or URN into the inspiration library through Unipile's documented post endpoint. This is the migration/manual lane; normal capture is automatic when a URL is pasted into the configured Secretary WhatsApp group.",
388
+ inputSchema: {
389
+ type: "object",
390
+ properties: {
391
+ source: { type: "string", minLength: 1, maxLength: 2048 },
392
+ source_author: { type: "string", minLength: 1, maxLength: 1024 },
393
+ federico_note: { type: "string", minLength: 1, maxLength: 16384 },
394
+ purpose: { type: "string", minLength: 1, maxLength: 4096 },
395
+ content_kind: { type: "string", enum: ["post_format", "business_idea"] },
396
+ credit_required: { type: "boolean" },
397
+ credit_note: { type: "string", minLength: 1, maxLength: 4096 },
398
+ format_description: { type: "string", minLength: 1, maxLength: 4096 },
399
+ },
400
+ required: ["source"],
401
+ additionalProperties: false,
402
+ },
403
+ },
404
+ {
405
+ name: "sd_inspiration_channel_configure",
406
+ path: "/sd/inspiration/channel/configure",
407
+ description: "Verify and bind the exact Secretary WhatsApp group against the connected account and live chat list, then enable automatic LinkedIn URL capture and same-group acknowledgements. Never use a self-chat fallback.",
408
+ inputSchema: {
409
+ type: "object",
410
+ properties: {
411
+ chat_id: { type: "string", minLength: 1, maxLength: 500 },
412
+ provider_id: { type: "string", minLength: 1, maxLength: 500 },
413
+ chat_name: { type: "string", minLength: 1, maxLength: 200 },
414
+ confirm: { type: "boolean", const: true },
415
+ },
416
+ required: ["chat_id", "provider_id", "chat_name", "confirm"],
417
+ additionalProperties: false,
418
+ },
419
+ },
420
+ {
421
+ name: "sd_inspiration_channel_set",
422
+ path: "/sd/inspiration/channel/set",
423
+ description: "Database kill switch for automatic inspiration capture and acknowledgements. Disabling requires no deploy or restart.",
424
+ inputSchema: {
425
+ type: "object",
426
+ properties: {
427
+ capture_enabled: { type: "boolean" },
428
+ confirm: { type: "boolean", const: true },
429
+ },
430
+ required: ["capture_enabled", "confirm"],
431
+ additionalProperties: false,
432
+ },
433
+ },
340
434
  {
341
435
  name: "sd_secretary_reject",
342
436
  path: "/sd/secretary/reject",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floomhq/signaldash",
3
- "version": "0.33.2",
3
+ "version": "0.35.0",
4
4
  "description": "Secure LinkedIn, WhatsApp, and email access for AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "scripts": {
20
20
  "test": "node --test",
21
- "check": "node --check bin/sd.mjs && node --check server/server.cjs && node --check server/composio-email.cjs && node --check server/attachments.cjs && node --check server/write-control.cjs && node --check server/secretary-store.cjs && node --check server/secretary-collector.cjs && node --check server/secretary-latest.cjs && node --check server/secretary-approvals.cjs && node --check server/secretary-rules.cjs && node --check server/secretary-shadow-gate.cjs && node --check server/secretary-vault-importer.cjs && node --check server/linkedin-archive-importer.cjs && node --check server/voice-profile.cjs && node --check server/campaign-store.cjs && node --check server/campaign-runner.cjs && node --check server/withdrawal-store.cjs && node --check server/post-scheduler.cjs && node --check server/message-scheduler.cjs && node --check scripts/import-linkedin-archive.mjs && node --check scripts/import-secretary-vault-snapshot.mjs && node --check scripts/rebuild-secretary-actors.mjs && node --check bin/signaldash.js && node --check lib/cli.js && node --check lib/config-file.js && node --check lib/mcp.js && node --check lib/rate-guard.js && node --check lib/secrets.js && node --check lib/unipile.js"
21
+ "check": "node --check bin/sd.mjs && node --check server/server.cjs && node --check server/composio-email.cjs && node --check server/attachments.cjs && node --check server/write-control.cjs && node --check server/secretary-store.cjs && node --check server/secretary-collector.cjs && node --check server/secretary-latest.cjs && node --check server/secretary-approvals.cjs && node --check server/secretary-push.cjs && node --check server/secretary-rules.cjs && node --check server/secretary-shadow-gate.cjs && node --check server/secretary-vault-importer.cjs && node --check server/secretary-inspiration.cjs && node --check server/linkedin-archive-importer.cjs && node --check server/voice-profile.cjs && node --check server/campaign-store.cjs && node --check server/campaign-runner.cjs && node --check server/withdrawal-store.cjs && node --check server/post-scheduler.cjs && node --check server/message-scheduler.cjs && node --check scripts/import-linkedin-archive.mjs && node --check scripts/import-secretary-vault-snapshot.mjs && node --check scripts/rebuild-secretary-actors.mjs && node --check bin/signaldash.js && node --check lib/cli.js && node --check lib/config-file.js && node --check lib/mcp.js && node --check lib/rate-guard.js && node --check lib/secrets.js && node --check lib/unipile.js"
22
22
  },
23
23
  "keywords": [
24
24
  "mcp",
@@ -5,6 +5,42 @@ description: Render Federico's stored inbound SignalDash triage when he asks for
5
5
 
6
6
  # Secretary latest
7
7
 
8
+ ## Standing operating rules
9
+
10
+ Apply this priority order to the rows SignalDash returns. Do not reorder rows
11
+ inside one server category:
12
+
13
+ 1. Always do: every inbound comment on Federico's own posts gets a drafted
14
+ reply and a like. This includes short, generic, and critical comments.
15
+ Critical replies stay factual, calm, and non-defensive. Every commenter and
16
+ reactor is captured as a signal and checked against the ICP while the post
17
+ is still live.
18
+ 2. Same day: expiring travel or location context, concrete scheduling options,
19
+ and threads where Federico wrote last.
20
+ 3. Within 24 hours: real-fund investors, network intro offers, design partners,
21
+ customers, and existing valuable conversations.
22
+ 4. Batch at low priority: student or junior mentoring, vague sparring or
23
+ participation offers, and internship requests under posts.
24
+ 5. Ignore: cold agency or automation pitches and generic tool sellers.
25
+
26
+ Draft in the counterparty's language only when it is English or German. Use
27
+ English for every other language. Never reply in Italian or another language
28
+ Federico does not speak, because doing so represents that he speaks it.
29
+
30
+ Nothing in this skill auto-sends. Federico approves every exact reply, comment
31
+ reply, like, or other third-party action until he explicitly changes that
32
+ rule. SignalDash separately owns one server-rendered exception: when explicitly
33
+ enabled, an hourly change-only notice may go to Federico's exact verified
34
+ Secretary WhatsApp group. The skill does not compose or send that notice. The
35
+ server remains the authority for its dedupe, kill switch, group proof,
36
+ read-before-send guard, and exact readback.
37
+
38
+ When Federico asks for inspiration or formats, call `sd_inspiration_list`.
39
+ Use `offen` post formats unless he explicitly asks for business ideas or history.
40
+ Keep the returned `draft_provenance` attached to any draft. Add a credit line
41
+ when `credit_required` is true or when recognisable framing or wording is
42
+ borrowed. A `genutzt` entry is terminal and must never be proposed again.
43
+
8
44
  When Federico asks `latest`, call `sd_secretary_latest`. This is a stored-data
9
45
  read. Do not call LinkedIn, list chats, read threads, draft with a model, or use
10
46
  any provider-backed tool as part of this flow.
@@ -364,6 +364,12 @@ Use the exact tool names and argument keys below. Limits are optional.
364
364
  |---|---|---|
365
365
  | `sd_version` | no arguments | Read the backend commit, dirty-at-start state, process start time, and package version captured when the serving process started. Use it to distinguish stale deployment from a code failure. |
366
366
  | `sd_secretary_latest` | `limit` optional integer 1-100, default 50; `continuation` optional signed token; `ack_token` optional signed token from the previous successful response | Read the stored Secretary inbox with zero provider calls. Render its rows plus the ignored aggregate as one table. Preserve the prior tokens after an error; on the next successful call pass its acknowledgement and continuation exactly as returned. |
367
+ | `sd_secretary_push_set` | `enabled` boolean and `confirm:true` required | Enable or disable change-only hourly notifications to Federico's exact verified Secretary WhatsApp group. Enabling re-proves the account and group from the live chat list and starts from that instant. Disabling is an immediate database kill switch and needs no deploy or restart. |
368
+ | `sd_inspiration_list` | `limit` optional 1-100, default 20; `status` optional `offen`, `in arbeit`, `genutzt`, or `alle`; `content_kind` optional `post_format`, `business_idea`, or `all` | Read stored inspiration ranked by source engagement with zero provider calls. Defaults exclude genutzt entries and business ideas. Preserve every row's `draft_provenance`, and add credit when `credit_required` is true or recognisable framing or wording is reused. |
369
+ | `sd_inspiration_status` | `id`, `status`, and `confirm:true` required; `resulting_post_urn` required exactly when status is `genutzt` | Record offen, in arbeit, or genutzt state. Genutzt is terminal and the resulting own-post URN prevents the source from ever being proposed again. |
370
+ | `sd_inspiration_import` | `source` exact LinkedIn post URL or URN; optional source author, Federico note, purpose, content kind, credit fields, and format description | Migration/manual capture through Unipile's documented post retrieval endpoint. The primary capture path remains pasting a URL into the verified Secretary WhatsApp group. |
371
+ | `sd_inspiration_channel_configure` | exact `chat_id`, `provider_id`, `chat_name`, and `confirm:true` | Re-prove the connected WhatsApp account and exact group in the live chat list, then enable automatic URL capture and same-group acknowledgements. Never substitute a self-chat. |
372
+ | `sd_inspiration_channel_set` | `capture_enabled` and `confirm:true` | Disable or re-enable capture and acknowledgements through the database kill switch without a deploy. |
367
373
  | `sd_secretary_approve` | `disposition_id` required; `payload_hash` required exact 64-character hash from latest; `confirm:true` required | Create one single-use, 15-minute receipt for the exact current stored draft. It derives the sender and executable payload from storage. |
368
374
  | `sd_secretary_reject` | `disposition_id` required; `confirm:true` required | Reject one exact current stored draft. It sends nothing. |
369
375
  | `li_list_chats` | `limit` integer 1-100, default 20; `cursor` optional; `search` optional string, max 200 characters; `max_scan` optional integer 1-500; `unread` optional boolean | Find recent LinkedIn chats, unread counts, and exact `chat_id` values. `unread:true` is forwarded to the provider as `unread=true`; SignalDash does not fetch a full chat page and filter it locally. Search accepts a unique stored display name, exact `public_id`, member id, or ordinary chat field. A stored name/public id is resolved to its verified member id before matching, so a provider row with `name:null` remains findable. Without an explicit `max_scan`, a zero-match search extends from 200 up to a hard 500-chat/five-page bound; explicit bounds remain exact. Read `scanned_chats`, `pages_fetched`, `scan_limit`, and `exhaustive` before concluding absence. The response also reports any resolved public/member ids. Any other key, including `text` and `member_id`, is refused with `unsupported_parameter` rather than accepted and ignored. |
@@ -426,6 +432,8 @@ Representative calls:
426
432
  ```text
427
433
  sd_version({})
428
434
  sd_secretary_latest({})
435
+ sd_secretary_push_set({"enabled":false,"confirm":true})
436
+ sd_inspiration_list({})
429
437
  li_list_chats({"limit":20})
430
438
  li_read_messages({"chat_id":"chat_li_7f3a","limit":20})
431
439
  li_send_message({"chat_id":"chat_li_7f3a","text":"Yes. I’ll send it this afternoon."})
@@ -1236,9 +1244,13 @@ These rules apply to LinkedIn messages and invitations, WhatsApp, email, and
1236
1244
  public LinkedIn posts.
1237
1245
 
1238
1246
  1. Never send or publish without explicit human approval of the exact
1239
- recipient or audience and the exact final text. The only standing-action
1240
- exception is invitation auto-accept after explicit approval of its exact
1241
- persistent setting and filters.
1247
+ recipient or audience and the exact final text. The standing-action
1248
+ exceptions are invitation auto-accept after explicit approval of its exact
1249
+ persistent setting and filters, and the server-rendered hourly Secretary
1250
+ notification to Federico's exact verified Secretary WhatsApp group after
1251
+ `sd_secretary_push_set` is explicitly enabled. The latter never sends to a
1252
+ third party, never uses a self-chat, and sends nothing when no stored change
1253
+ exists.
1242
1254
  2. Read the exact thread immediately before a message action. For invitations,
1243
1255
  preview the exact target and note or list the exact current invitation.
1244
1256
  Check the recipient, latest inbound message, prior context, relationship,
@@ -20,6 +20,13 @@ Treat LinkedIn, WhatsApp, and email as human accounts, not bulk messaging APIs.
20
20
  the user has not already approved both.
21
21
  6. Send one message, then read the thread again to confirm delivery.
22
22
 
23
+ The only Secretary notification exception is server-rendered and goes to
24
+ Federico's exact verified Secretary WhatsApp group after its database setting
25
+ is explicitly enabled. It re-resolves that group live, never uses a self-chat,
26
+ sends only for a newly stored exact signal or draft identity, and sends nothing
27
+ on a no-change cycle. This exception grants no authority to contact a third
28
+ party.
29
+
23
30
  Never infer a recipient from a partial name. Never send blind. Never retry a
24
31
  send after an ambiguous timeout without first reading the thread.
25
32