@floomhq/signaldash 0.40.0 → 0.41.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
@@ -120,7 +120,7 @@ setup installs both from the same pinned npm package
120
120
  the human chose to execute:
121
121
 
122
122
  ```bash
123
- npx -y @floomhq/signaldash@0.40.0 <invite-code>
123
+ npx -y @floomhq/signaldash@0.41.0 <invite-code>
124
124
  ```
125
125
 
126
126
  Run that command in a terminal, not in an agent chat. Do not ask an agent to
@@ -218,6 +218,7 @@ timer, scheduler entry, Buffer item, or provider write.
218
218
  - `li_like_comment(post_id, parent_comment_id, comment_id, expected_watermark?)`
219
219
  - `li_delete_message(chat_id, message_id, confirm)`
220
220
  - `li_delete_comment(post_id, comment_id, confirm)`
221
+ - `li_delete_post(post_id, expected_text_prefix, confirm)` (own post only, bound account only, capability `linkedin_post_delete`)
221
222
  - `li_draft_post(text, publish, scheduled_at?, content_pipeline_id?, content_pipeline_override?, mentions?, attachments?, first_comment?, confirm?, approval_hash?)`
222
223
  - `li_set_scheduled_post_first_comment(id, first_comment, confirm)`
223
224
  - `li_save_post_draft(text, mentions?, attachments?, first_comment?, source_key?, metadata?)`
package/bin/sd.mjs CHANGED
@@ -864,12 +864,14 @@ const TOOLS = [
864
864
  {
865
865
  name: "li_send_invitation",
866
866
  path: "/li/send_invitation",
867
- description: "Preview or send one exact LinkedIn invitation. First call without confirm, obtain approval, then repeat the exact provider_id and note with confirm:true.",
867
+ description: "Preview or send one exact LinkedIn invitation. First call without confirm, obtain approval, then repeat the exact provider_id, note, follow_up and note_mode with confirm:true. DEFAULT: a note is NOT put on the invitation (free accounts get notes refused); the invitation goes out bare and the note text is sent once as the first message after the person is proven to have accepted. Set note_mode \"inline\" only when the note must ride on the invitation itself. The preview shows the exact follow-up text; list or cancel pending follow-ups with sd_invitation_followups / sd_invitation_followup_cancel.",
868
868
  inputSchema: {
869
869
  type: "object",
870
870
  properties: {
871
871
  provider_id: { type: "string", minLength: 1, maxLength: 500 },
872
- note: { type: "string", maxLength: 300 },
872
+ note: { type: "string", maxLength: 300, description: "With the default note_mode follow_up this text becomes the after-acceptance message; with note_mode inline it rides on the invitation." },
873
+ follow_up: { type: "string", minLength: 1, maxLength: 5000, description: "Exact message to send once after acceptance. Use instead of note (default mode), or alongside an inline note." },
874
+ note_mode: { type: "string", enum: ["follow_up", "inline"], default: "follow_up" },
873
875
  confirm: { type: "boolean", default: false },
874
876
  },
875
877
  required: ["provider_id"],
@@ -1859,6 +1861,21 @@ const TOOLS = [
1859
1861
  additionalProperties: false,
1860
1862
  },
1861
1863
  },
1864
+ {
1865
+ name: "li_delete_post",
1866
+ path: "/li/delete_post",
1867
+ description: "Delete ONE LinkedIn post authored by this authenticated account. Irreversible; disabled unless the operator enables the linkedin_post_delete capability. Acts only as the account bound to this SignalDash session. Requires the exact social_id from li_my_posts (urn:li:activity:<digits>), expected_text_prefix (the first 10-500 characters of the post text, exactly) and confirm:true. Before deleting, SignalDash reads the post with the same account and refuses unless the author is this sender (post_not_own), it is not a repost, and the text starts with expected_text_prefix (text_prefix_mismatch). Returns the post evidence and a post-delete readback; a replay of the same post is refused as duplicate_delete. Deletion is remediation, not rollback.",
1868
+ inputSchema: {
1869
+ type: "object",
1870
+ properties: {
1871
+ post_id: { type: "string", pattern: "^urn:li:activity:[0-9]{1,30}$", maxLength: 60 },
1872
+ expected_text_prefix: { type: "string", minLength: 10, maxLength: 500 },
1873
+ confirm: { type: "boolean", const: true },
1874
+ },
1875
+ required: ["post_id", "expected_text_prefix", "confirm"],
1876
+ additionalProperties: false,
1877
+ },
1878
+ },
1862
1879
  {
1863
1880
  name: "li_draft_post",
1864
1881
  path: "/li/create_post",
@@ -2325,6 +2342,48 @@ const TOOLS = [
2325
2342
  additionalProperties: false,
2326
2343
  },
2327
2344
  },
2345
+ {
2346
+ name: "sd_invitation_followups",
2347
+ path: "/sd/invitation_followups",
2348
+ description: "List this user's invitation follow-ups: exact messages that are sent once a LinkedIn invitation is proven accepted. States: pending (waiting for acceptance, or accepted and waiting for a send slot), sending, sent, cancelled, expired (not accepted within 30 days), needs_review (the thread moved, e.g. they wrote first, or the outcome is unknown; never retried automatically).",
2349
+ inputSchema: {
2350
+ type: "object",
2351
+ properties: {
2352
+ state: { type: "string", enum: ["pending", "sending", "sent", "cancelled", "expired", "needs_review"] },
2353
+ },
2354
+ additionalProperties: false,
2355
+ },
2356
+ },
2357
+ {
2358
+ name: "sd_invitation_followup_create",
2359
+ path: "/sd/invitation_followup_create",
2360
+ description: "Register an after-acceptance follow-up message for an invitation that was ALREADY sent. First call without confirm: SignalDash proves a pending sent invitation to this exact provider_id exists and shows the exact text. After the human approves, repeat the same provider_id, text and invitation_id with confirm:true.",
2361
+ inputSchema: {
2362
+ type: "object",
2363
+ properties: {
2364
+ provider_id: { type: "string", minLength: 1, maxLength: 500 },
2365
+ text: { type: "string", minLength: 1, maxLength: 5000 },
2366
+ invitation_id: { type: "string", minLength: 1, maxLength: 500 },
2367
+ confirm: { type: "boolean", default: false },
2368
+ },
2369
+ required: ["provider_id", "text"],
2370
+ additionalProperties: false,
2371
+ },
2372
+ },
2373
+ {
2374
+ name: "sd_invitation_followup_cancel",
2375
+ path: "/sd/invitation_followup_cancel",
2376
+ description: "Cancel one exact invitation follow-up while it is still pending. Requires id and confirm:true. It cannot stop or unsend one already being sent or sent.",
2377
+ inputSchema: {
2378
+ type: "object",
2379
+ properties: {
2380
+ id: { type: "string", format: "uuid" },
2381
+ confirm: { type: "boolean", const: true },
2382
+ },
2383
+ required: ["id", "confirm"],
2384
+ additionalProperties: false,
2385
+ },
2386
+ },
2328
2387
  {
2329
2388
  name: "sd_followup_create",
2330
2389
  path: "/sd/followup_create",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floomhq/signaldash",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "Secure LinkedIn, WhatsApp, and email access for AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "scripts": {
21
21
  "test": "node --test",
22
- "check": "node --check bin/sd.mjs && node --check server/server.cjs && node --check server/outbound-text-policy.cjs && node --check server/intro-request-notifier.cjs && node --check server/content-pipeline.cjs && node --check server/x-signal-engine.cjs && node --check server/buffer-calendar.cjs && node --check server/composio-email.cjs && node --check server/attachments.cjs && node --check server/media-fetch.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/draft-rewrite-worker.cjs && node --check server/message-scheduler.cjs && node --check server/wa-chat-index.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 scripts/extract-conversation-inspiration.mjs && node --check scripts/render-content-board.mjs && node --check scripts/collect-x-signals.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 && node --check lib/x-signal-collector.cjs"
22
+ "check": "node --check bin/sd.mjs && node --check server/server.cjs && node --check server/outbound-text-policy.cjs && node --check server/intro-request-notifier.cjs && node --check server/content-pipeline.cjs && node --check server/x-signal-engine.cjs && node --check server/buffer-calendar.cjs && node --check server/composio-email.cjs && node --check server/attachments.cjs && node --check server/media-fetch.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/draft-rewrite-worker.cjs && node --check server/message-scheduler.cjs && node --check server/invitation-followups.cjs && node --check server/wa-chat-index.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 scripts/extract-conversation-inspiration.mjs && node --check scripts/render-content-board.mjs && node --check scripts/collect-x-signals.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 && node --check lib/x-signal-collector.cjs"
23
23
  },
24
24
  "keywords": [
25
25
  "mcp",
@@ -417,7 +417,7 @@ Use the exact tool names and argument keys below. Limits are optional.
417
417
  | `li_mark_read` | `chat_id` required | Explicitly clear one LinkedIn chat's unread state. Reading never clears unread automatically. |
418
418
  | `li_start_chat` | `member_ids` required array of 1-10 exact `ACo`, `ACw`, or `AE` provider member IDs; `text` required exact first message; `confirm`, `approval_hash`, and `dry_run:true` apply only after preview | Start one direct or group chat. Preview first, show the complete member-ID set and exact text, then repeat that exact payload with the returned approval hash only after explicit approval. SignalDash resolves every member live, blocks protected or suppressed contacts, returns an existing exact member-set chat without sending, and charges one thread-message plus aggregate action for a new chat regardless of member count. `dry_run:true` proves the full path up to the provider write without consuming approval or budget. |
419
419
  | `li_send_message` | Manual path: `chat_id` and `text` required; `expected_watermark` optional exact 64-character watermark; `mark_read` optional boolean, default true. Secretary path: `secretary_receipt_id` alone. | Send one approved LinkedIn reply after an immediate read of that exact chat. A Secretary receipt derives the exact stored chat and text and refuses every caller-supplied override. |
420
- | `li_send_invitation` | `provider_id` required; `note` optional, max 300 exact characters; `confirm` optional, default false | First preview one exact target and note. The server verifies relationship, both invitation directions, and absence of an existing one-to-one chat. After exact approval, repeat the identical call with `confirm:true`; jitter completes before the final preflight and action reservation. |
420
+ | `li_send_invitation` | `provider_id` required; `note` optional, max 300 exact characters; `follow_up` optional, max 5000; `note_mode` optional, `follow_up` (default) or `inline`; `confirm` optional, default false | First preview one exact target, note and follow-up. By default a note is NOT put on the invitation (free accounts get notes refused with provider_http_400/422): the invitation goes out bare and the note text becomes a pending invitation follow-up, sent once as the first message after the person is proven to have accepted. `note_mode:"inline"` keeps the note on the invitation. The server verifies relationship, both invitation directions, and absence of an existing one-to-one chat. After exact approval, repeat the identical call with `confirm:true`; jitter completes before the final preflight and action reservation. |
421
421
  | `li_invitations_received` | `limit` integer 1-100, default 50; `cursor` optional | List one bounded page of received invitations. This read authorizes only the exact returned invitation IDs for a later accept. |
422
422
  | `li_accept_invitation` | `invitation_id` required; `confirm:true` required | Accept one exact currently pending received invitation after a fresh `li_invitations_received` read and approval. |
423
423
  | `li_invitations_sent` | `limit` integer 1-100, default 50; `cursor` optional | List one bounded page of sent invitations. This read authorizes only the exact returned invitation IDs for a later withdrawal. |
@@ -478,6 +478,9 @@ Use the exact tool names and argument keys below. Limits are optional.
478
478
  | `sd_schedule_message` | `channel` required, `whatsapp` or `linkedin`; `chat_id` required, max 500; `text` required, max 5000; `scheduled_at` required offset-qualified ISO date-time from 60 seconds to 365 days ahead; `confirm:true` required | Schedule one exact message into one chat you have already read. Read that exact chat first, at `limit` 10 or more on LinkedIn: SignalDash records what the thread looked like and refuses at send time if the conversation moved. Text only; attachments are refused rather than dropped. One message at one time, never a sequence. |
479
479
  | `sd_scheduled_messages` | `state` optional, one of `scheduled`, `executing`, `sent`, `cancelled`, `failed`, `needs_review`; `channel` optional | List only this authenticated user's scheduled messages and their durable states. Returns every matching row, unpaginated, and always reports `needs_review_count` outside your filter. |
480
480
  | `sd_cancel_scheduled_message` | `id` required UUID; `confirm:true` required | Cancel one exact message while its state is still `scheduled`. It cannot stop one already being sent, and it cannot unsend one that has been sent. |
481
+ | `sd_invitation_followups` | `state` optional: `pending`, `sending`, `sent`, `cancelled`, `expired`, `needs_review` | List invitation follow-ups and their durable states, with `needs_review_count`. Acceptance is proven hourly per pending row (invitation gone from a fully read sent list AND first-degree, or a chat exists); the send goes through the paced `li_send_message` write path once. If they already wrote, or the thread holds an outbound message, nothing is sent and the row becomes `needs_review`. Not accepted within 30 days: `expired`. |
482
+ | `sd_invitation_followup_create` | `provider_id`, `text` required; `invitation_id` optional; `confirm` optional | Register a follow-up for an invitation that was already sent. Preview proves a pending sent invitation to this exact person; after approval repeat the identical call with `confirm:true`. One pending follow-up per person. |
483
+ | `sd_invitation_followup_cancel` | `id` required UUID; `confirm:true` required | Cancel one exact follow-up while it is still `pending`. It cannot stop or unsend one being sent or sent. |
481
484
  | `sd_followup_create` | `channel`, exact `thread_id`, task `context`, and offset-qualified `due_at` required; optional completion condition, auto-close choice, recipient label, origin, source message, and baseline | Record one independent task inside a LinkedIn, WhatsApp, email, or Slack conversation. Multiple different tasks may remain active in the same thread. Monitoring only: this never sends. |
482
485
  | `sd_followups` | optional `status`, `channel`, and `overdue` filters | Reconcile and list task-level expectations. A reply either completes an explicitly auto-close task or moves it to `needs_review`; it never clears unrelated tasks in the same thread. |
483
486
  | `sd_followup_cancel` | `id` required UUID; `confirm:true` required | Cancel one exact active task without deleting communication history or sending anything. |