Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugins/leadbay/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
"name": "leadbay",
"version": "0.41.0",
"version": "0.41.1",
"description": "AI lead discovery, qualification, and outreach prep on your Leadbay account.",
"author": {
"name": "Leadbay",
Expand Down
8 changes: 5 additions & 3 deletions packages/components/src/usage-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -531,9 +531,9 @@ spacing CSS of your own:
<div class="lb-section">
<div class="lb-sec-title">Outreach</div>
<div class="lb-stack"> <!-- one control per line -->
<select class="lb-select" aria-label="Outreach result for Acme Corp"></select>
<div class="lb-actions" role="group"><!-- the 4 prospecting toggles, see *Writing from a page* --></div>
<input class="lb-input" aria-label="Outreach note for Acme Corp">
<button class="lb-btn lb-btn-submit">Log outreach</button>
<button class="lb-btn lb-btn-submit">Log outreach</button> <!-- the note: lb.note, never lb.outreach -->
</div>
</div>
<details class="lb-section"><!-- lazy full profile, see below --></details>
Expand Down Expand Up @@ -1660,7 +1660,9 @@ refreshBtn.onclick = () => job.refresh();

## Write-call rules

The domain factories handle these for you. If you hand-roll an action:
The domain factories handle these for you. A page's buttons never call
`leadbay_report_outreach` — see *Writing from a page*; the rule below is for
an agent logging an outreach itself. If you hand-roll an action:
`leadbay_report_outreach` args MUST include `verification:{source:"user_confirmed", ref}`
AND `_triggered_by`; `leadbay_add_leads_to_campaign` needs `_triggered_by`;
`add_note`/`like_lead`/`dislike_lead` take only their own args. `epilogue_status` is
Expand Down
39 changes: 39 additions & 0 deletions packages/components/test/triage-card-writes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, it, expect } from "vitest";
import { ARTIFACT_USAGE_GUIDE as GUIDE } from "../../core/src/artifact-runtime.generated.js";

// The triage board is THE default board, and its card template is the markup
// an agent copies. After 0.41.0 the prose around it said "toggles + lb.note"
// while the template still drew the old outcome select and a Log outreach
// button — so a board built from the template shipped the 60-second hang the
// release removed everywhere else. Pinned here because the template, not the
// prose, is what gets copied.

const recipe = () =>
GUIDE.slice(
GUIDE.indexOf("## Recipe: the pull-leads triage board"),
GUIDE.indexOf("## Recipe: the ROUTE PLANNER"),
);

describe("the triage card template draws the web app's writes", () => {
it("puts the prospecting toggles in the Outreach section, not an outcome select", () => {
// The select duplicated the toggles as a second writer of one field; the
// button stays, now saving the note.
const r = recipe();
expect(r).toContain("the 4 prospecting toggles, see *Writing from a page*");
expect(r).not.toContain("Outreach result for Acme Corp");
});

it("saves the note through lb.note", () => {
expect(recipe()).toContain("the note: lb.note, never lb.outreach");
});
});

describe("the write-call rules do not read as permission for pages", () => {
it("say a page never calls report_outreach before explaining how to hand-roll it", () => {
const rules = GUIDE.slice(GUIDE.indexOf("## Write-call rules"), GUIDE.indexOf("## Degradation"));
const never = rules.indexOf("A page's buttons never call");
const handRoll = rules.indexOf("args MUST include");
expect(never).toBeGreaterThan(-1);
expect(never).toBeLessThan(handRoll);
});
});
2 changes: 1 addition & 1 deletion packages/core/src/artifact-runtime.generated.ts

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions packages/mcp/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog — @leadbay/mcp

## 0.41.1 — 2026-09-26 — triage boards stop drawing a second outcome control

- **Triage boards are built with the same outreach controls as the web app.**
The template the assistant copies for a triage board still drew an old
"Outreach result" menu next to the prospecting-action buttons — two controls
changing the same thing. New boards now get only the four prospecting
actions and a note, and the note saves straight away.

## 0.41.0 — 2026-09-25 — boards a rep can work from: a lead desk, a route planner, and buttons that answer

- **Every Leadbay board is built from the same kit.** Asking for a triage board,
Expand Down
2 changes: 1 addition & 1 deletion packages/mcp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@leadbay/mcp",
"version": "0.41.0",
"version": "0.41.1",
"mcpName": "io.github.leadbay/leadbay-mcp",
"description": "Model Context Protocol (MCP) server for Leadbay — AI lead discovery, qualification, and enrichment for Claude Desktop, Cursor, and Claude Code.",
"type": "module",
Expand Down
4 changes: 2 additions & 2 deletions packages/mcp/server.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "io.github.leadbay/leadbay-mcp",
"title": "Leadbay",
"description": "AI lead discovery, qualification, and outreach prep on your Leadbay account.",
"version": "0.41.0",
"version": "0.41.1",
"repository": {
"url": "https://github.com/leadbay/mcp",
"source": "github",
Expand All @@ -24,7 +24,7 @@
"registryType": "npm",
"registryBaseUrl": "https://registry.npmjs.org",
"identifier": "@leadbay/mcp",
"version": "0.41.0",
"version": "0.41.1",
"transport": {
"type": "stdio"
},
Expand Down
Loading