sproutkit-code 1.5.0 → 1.5.2
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/dist/commands/sproutkit-leads.md +7 -7
- package/dist/index.js +75 -9
- package/dist/skill/SKILL.md +7 -2
- package/package.json +1 -1
|
@@ -3,14 +3,14 @@ description: Show current leads and their stage
|
|
|
3
3
|
argument-hint: "[filter] e.g. site_built, or Leeds"
|
|
4
4
|
allowed-tools: Bash(sproutkit *)
|
|
5
5
|
---
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
!`sproutkit list --compact 2>/dev/null`
|
|
6
|
+
!`sproutkit list --limit 100 2>/dev/null`
|
|
9
7
|
|
|
10
8
|
The operator asked to see: $ARGUMENTS
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
The table above is the CLI's own formatted output — aligned columns, live links,
|
|
11
|
+
a delivered marker and a stage tally.
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
Print it back VERBATIM inside a code block. Do NOT rebuild it as a markdown
|
|
14
|
+
table, do not reformat or re-order it, do not truncate it, do not add commentary.
|
|
15
|
+
If they asked for a subset (a stage or a town), show only those rows but keep the
|
|
16
|
+
formatting exactly as-is, including the header.
|
package/dist/index.js
CHANGED
|
@@ -94446,7 +94446,10 @@ Interested?`;
|
|
|
94446
94446
|
const status = input.status;
|
|
94447
94447
|
const city = input.city;
|
|
94448
94448
|
const limit = Math.min(Number(input.limit ?? 25), 100);
|
|
94449
|
-
let sql =
|
|
94449
|
+
let sql = `SELECT id, name, status, type, city, phone, email, site_url, website, lead_kind,
|
|
94450
|
+
booking_status, booking_platform, booking_url, admin_url, custom_domain,
|
|
94451
|
+
handed_over_at
|
|
94452
|
+
FROM leads`;
|
|
94450
94453
|
const conds = [];
|
|
94451
94454
|
const params = [];
|
|
94452
94455
|
if (status) {
|
|
@@ -95833,7 +95836,7 @@ var require_package2 = __commonJS({
|
|
|
95833
95836
|
"package.json"(exports2, module2) {
|
|
95834
95837
|
module2.exports = {
|
|
95835
95838
|
name: "sproutkit-code",
|
|
95836
|
-
version: "1.5.
|
|
95839
|
+
version: "1.5.2",
|
|
95837
95840
|
description: "Sproutkit in your terminal \u2014 find leads, build sites, run outreach, all via chat.",
|
|
95838
95841
|
bin: {
|
|
95839
95842
|
sproutkit: "./dist/index.js"
|
|
@@ -96963,10 +96966,64 @@ async function cmdList(argv) {
|
|
|
96963
96966
|
say(c.dim(' No leads yet. Try: sproutkit find "barbers in <area>"'));
|
|
96964
96967
|
return;
|
|
96965
96968
|
}
|
|
96969
|
+
renderLeadTable(rows);
|
|
96970
|
+
}
|
|
96971
|
+
var STAGE_LABEL = {
|
|
96972
|
+
discovered: "New",
|
|
96973
|
+
site_built: "Built",
|
|
96974
|
+
contacted: "Contacted",
|
|
96975
|
+
replied: "Replied",
|
|
96976
|
+
won: "Won",
|
|
96977
|
+
dead: "Dead"
|
|
96978
|
+
};
|
|
96979
|
+
function cell(text, width) {
|
|
96980
|
+
const t = text ?? "";
|
|
96981
|
+
if (t.length === width) return t;
|
|
96982
|
+
if (t.length < width) return t + " ".repeat(width - t.length);
|
|
96983
|
+
return width <= 1 ? t.slice(0, width) : t.slice(0, width - 1) + "\u2026";
|
|
96984
|
+
}
|
|
96985
|
+
function renderLeadTable(rows) {
|
|
96986
|
+
const term = process.stdout.columns && process.stdout.columns > 40 ? process.stdout.columns : 100;
|
|
96987
|
+
const idW = Math.max(3, ...rows.map((r) => String(r.id).length + 1));
|
|
96988
|
+
const stageW = Math.max(5, ...rows.map((r) => (STAGE_LABEL[r.status] ?? r.status).length));
|
|
96989
|
+
const placeW = Math.min(14, Math.max(5, ...rows.map((r) => (r.city || "").length)));
|
|
96990
|
+
const fixed = 2 + idW + 2 + stageW + 2 + placeW + 2;
|
|
96991
|
+
const nameW = Math.max(16, Math.min(34, term - fixed - 24));
|
|
96966
96992
|
say();
|
|
96993
|
+
say(
|
|
96994
|
+
" " + c.dim(
|
|
96995
|
+
cell("ID", idW) + " " + cell("BUSINESS", nameW) + " " + cell("STAGE", stageW) + " " + cell("AREA", placeW) + " WHAT THEY HAVE"
|
|
96996
|
+
)
|
|
96997
|
+
);
|
|
96998
|
+
say(" " + c.dim("\u2500".repeat(Math.min(term - 4, idW + nameW + stageW + placeW + 23))));
|
|
96967
96999
|
for (const r of rows) {
|
|
96968
|
-
const
|
|
96969
|
-
|
|
97000
|
+
const stage = STAGE_LABEL[r.status] ?? r.status;
|
|
97001
|
+
const stageColoured = r.status === "won" ? c.greenBold(cell(stage, stageW)) : r.status === "site_built" || r.status === "replied" ? c.green(cell(stage, stageW)) : r.status === "dead" ? c.dim(cell(stage, stageW)) : c.dim(cell(stage, stageW));
|
|
97002
|
+
const short = (u) => u.replace(/^https?:\/\//, "").replace(/\/$/, "");
|
|
97003
|
+
const assets = [];
|
|
97004
|
+
if (r.custom_domain) assets.push(c.cyan(r.custom_domain));
|
|
97005
|
+
else if (r.site_url) assets.push(short(r.site_url));
|
|
97006
|
+
if (r.booking_url) assets.push(r.site_url ? c.dim("+ booking") : short(r.booking_url));
|
|
97007
|
+
if (r.admin_url) assets.push(c.dim("+ admin"));
|
|
97008
|
+
if (!r.site_url && !r.booking_url && r.website) {
|
|
97009
|
+
assets.push(c.dim("own site: " + short(r.website)));
|
|
97010
|
+
}
|
|
97011
|
+
if (assets.length === 0) assets.push(c.dim("\u2014"));
|
|
97012
|
+
if (r.handed_over_at) assets.push(c.greenBold("\u2713 delivered"));
|
|
97013
|
+
say(
|
|
97014
|
+
" " + c.dim(cell("#" + r.id, idW)) + " " + c.bold(cell(r.name, nameW)) + " " + stageColoured + " " + c.dim(cell(r.city || "\u2014", placeW)) + " " + assets.join(c.dim(" \xB7 "))
|
|
97015
|
+
);
|
|
97016
|
+
}
|
|
97017
|
+
const counts = rows.reduce((acc, r) => {
|
|
97018
|
+
acc[r.status] = (acc[r.status] ?? 0) + 1;
|
|
97019
|
+
return acc;
|
|
97020
|
+
}, {});
|
|
97021
|
+
const order = ["discovered", "site_built", "contacted", "replied", "won", "dead"];
|
|
97022
|
+
const summary = order.filter((k) => counts[k]).map((k) => `${counts[k]} ${(STAGE_LABEL[k] ?? k).toLowerCase()}`).join(c.dim(" \xB7 "));
|
|
97023
|
+
say();
|
|
97024
|
+
say(" " + c.dim(`${rows.length} lead${rows.length === 1 ? "" : "s"} shown \u2014 `) + summary);
|
|
97025
|
+
if (rows.length >= 25) {
|
|
97026
|
+
say(c.dim(" More may exist \u2014 use --limit 100, or --status/--city to narrow."));
|
|
96970
97027
|
}
|
|
96971
97028
|
say();
|
|
96972
97029
|
}
|
|
@@ -97506,18 +97563,26 @@ var TASK_SYSTEM_PROMPT = `You operate the "sproutkit" CLI on the user's behalf.
|
|
|
97506
97563
|
HOW TO ACT \u2014 this is strict:
|
|
97507
97564
|
- Fulfil each request by running the matching sproutkit command(s) via Bash. Nothing else.
|
|
97508
97565
|
- Do NOT read, list, or explore the repo. Do NOT narrate a plan, think out loud, or look for a skill. No preamble, no "let me\u2026". Either ask a crisp question (below) or run the command.
|
|
97509
|
-
-
|
|
97566
|
+
- Pass --json for commands you need to READ data from (to get ids, urls, credentials).
|
|
97567
|
+
- EXCEPTION \u2014 \`sproutkit list\`: run it WITHOUT --json and print its output verbatim. It
|
|
97568
|
+
already prints a formatted table with links and a stage tally. Never re-render it yourself,
|
|
97569
|
+
never reformat it, never summarise it, never truncate it. Use --json for list ONLY when you
|
|
97570
|
+
need a field to feed into another command, and in that case don't display the JSON.
|
|
97510
97571
|
|
|
97511
97572
|
OUTPUT FORMAT \u2014 terse, scannable, NO editorialising:
|
|
97512
97573
|
- Never write rambling sentences or commentary about the results ("well short of 20, so the source is returning few matches" \u2014 DON'T). Just present the data.
|
|
97513
97574
|
- For find: one line "Found N (M new)", then one line per NEW lead: "#<id> <name> \xB7 <type>".
|
|
97514
|
-
- For list:
|
|
97575
|
+
- For list: print the command's own table output EXACTLY as it comes back. It is already
|
|
97576
|
+
formatted and aligned. Do not rebuild it as your own list, and do not cut it short.
|
|
97515
97577
|
- For build/book: one line "\u2713 <name> \u2014 <url>".
|
|
97516
|
-
-
|
|
97578
|
+
- For your OWN summaries use a plain "#<id> <name>" style \u2014 no fluff, no "Here's what I found".
|
|
97579
|
+
(This does not apply to \`sproutkit list\`, whose own table you pass straight through.)
|
|
97580
|
+
If a result count is low, state the number plainly \u2014 do NOT speculate about why unless asked.
|
|
97517
97581
|
|
|
97518
97582
|
GATHER REQUIRED CHOICES FIRST \u2014 ask, don't guess, don't chatter:
|
|
97519
97583
|
When a request is missing information the command needs, ask a SHORT, STRUCTURED question that lists the options \u2014 then wait. Present choices as a tight numbered/bulleted list, no rambling. Specifically:
|
|
97520
|
-
- Which business/lead is not clear \u2192 run \`sproutkit list --json
|
|
97584
|
+
- Which business/lead is not clear \u2192 run \`sproutkit list --json\` to read ids (don't print the
|
|
97585
|
+
JSON), then ask: "Which business?" and name a few (id + name).
|
|
97521
97586
|
- "make/build a booking site" \u2192 you MUST establish the booking TYPE before running. Ask: "What type of booking site?" and present exactly:
|
|
97522
97587
|
1. Slot-based \u2014 timed appointments (barbers, salons, clinics)
|
|
97523
97588
|
2. Reservation \u2014 table / party booking (restaurants, cafes)
|
|
@@ -97528,7 +97593,8 @@ When a request is missing information the command needs, ask a SHORT, STRUCTURED
|
|
|
97528
97593
|
COMMANDS:
|
|
97529
97594
|
- sproutkit find "<area>" --categories "<type>,<type>" --json \u2014 find website-less leads
|
|
97530
97595
|
- sproutkit find "<area>" --categories "\u2026" --booking --json \u2014 find businesses that HAVE a site but take bookings via WhatsApp/phone only (booking-page prospects)
|
|
97531
|
-
- sproutkit list
|
|
97596
|
+
- sproutkit list [--status <s>] [--city <c>] [--limit 100] \u2014 formatted table; SHOW IT VERBATIM
|
|
97597
|
+
- sproutkit list --json \u2014 same data as JSON, for reading ids only
|
|
97532
97598
|
- sproutkit build <id> --json [--instructions "..."] [--cms] [--multipage] \u2014 build a demo site (--multipage = real Home/Services/About/Contact pages, not one scroll)
|
|
97533
97599
|
- sproutkit build-all --json [--ids 3,5] [--concurrency 3] \u2014 build many at once
|
|
97534
97600
|
- sproutkit regenerate <id> --instructions "..." --json \u2014 rebuild an existing site with changes
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -17,7 +17,7 @@ do not need any API key yourself — just run the commands.
|
|
|
17
17
|
|
|
18
18
|
## Commands
|
|
19
19
|
|
|
20
|
-
All commands accept `--json` for structured output. **
|
|
20
|
+
All commands accept `--json` for structured output. **Pass `--json`** so
|
|
21
21
|
you can parse results reliably, then summarise them for the user in prose.
|
|
22
22
|
|
|
23
23
|
- **Find leads** — `sproutkit find "<area>" --categories "<type>,<type>" --json`
|
|
@@ -27,7 +27,12 @@ you can parse results reliably, then summarise them for the user in prose.
|
|
|
27
27
|
- Example: `sproutkit find "Shoreditch, London" --categories "barber shop,cafe" --json`
|
|
28
28
|
- Optional: `--max 25`, `--radius 3000`.
|
|
29
29
|
|
|
30
|
-
- **List leads** — `sproutkit list
|
|
30
|
+
- **List leads** — `sproutkit list` (optional `--status site_built`, `--city London`, `--limit 100`)
|
|
31
|
+
- Run it WITHOUT `--json` and show the output VERBATIM. It already prints an aligned
|
|
32
|
+
table with the live site/booking links, a delivered marker and a stage tally.
|
|
33
|
+
Do not re-render, reformat, summarise or truncate it — that throws the formatting away.
|
|
34
|
+
- Use `sproutkit list --json` only when you need a field to feed another command; in that
|
|
35
|
+
case read it and don't print it.
|
|
31
36
|
- Returns id, name, status, type, city, phone, site_url. Use this to get lead
|
|
32
37
|
**ids** before building or to report the pipeline.
|
|
33
38
|
|