@flowapt/flowiq-cli 0.9.5 → 0.9.6

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
@@ -1845,9 +1845,13 @@ flowiq plans status <plan_id> --to sent --commit
1845
1845
  timestamps instead of the send date (SAST day start) — "what did a client
1846
1846
  submit today", "what has moved since Friday", which `--since` cannot answer.
1847
1847
  - **`show`** prints the plan the way the dialog does: message copy, the
1848
- second message sent when a button is tapped, buttons with their URLs, the
1849
- creative (file name + link), audience, template link, the response to the
1850
- client, internal notes and the notes thread.
1848
+ second message sent when a button is tapped (named by the button's text),
1849
+ buttons with their targets, the creative (file name + link), audience,
1850
+ template link, the response to the client, internal notes and the notes
1851
+ thread. A marketing plan carries 0-10 buttons in any mix WhatsApp allows:
1852
+ `quick_reply`, `url` (up to 2, `→ link`), `phone` (1, `→ call +27…`) and
1853
+ `copy_code` (1, `→ code SPRING20`); each quick reply may have its own
1854
+ follow-up message (`slide2a`, `slide2b`, `slide2c` … by button position).
1851
1855
  - **`status`** is a dry run until `--commit`. `--comment` is the response the
1852
1856
  **client reads**; `--internal` is staff-only. `approved` and `rejected`
1853
1857
  record you as the reviewer; `rejected` requires `--comment`. Every commit is
@@ -1894,6 +1898,12 @@ flowiq test cleanup <organization_id> --confirm # delete the stress contact
1894
1898
  `--agent <id>` targets a specific (non-active) agent. `test stress cleanup` is
1895
1899
  destructive and requires `--confirm`.
1896
1900
 
1901
+ `test clear` (and `--clear` on `send`, and the clear between scenario turns) hides the
1902
+ messages (`memory_cutoff`) AND sets aside the agent's remembered tool results
1903
+ (`more_data.tool_usage_history`, which the agent reads as TOOL USAGE HISTORY) under
1904
+ `more_data.tool_usage_history_cleared`, so a cleared test really starts fresh. Since 0.9.6;
1905
+ before that earlier tool results and escalation reasons leaked into "cleared" tests.
1906
+
1897
1907
  ### Guide — `flowiq guide`
1898
1908
 
1899
1909
  Read the bundled docs in the terminal — no digging through node_modules.
package/TEAM-GUIDE.md CHANGED
@@ -116,6 +116,7 @@ When you see it, run `npm i -g @flowapt/flowiq-cli` — a stale version also mea
116
116
  | Agent can't quote ANY price / "I can't pull the live menu" | `flowiq agent config <org_id> --tool product_lookup=true` — name-based fuzzy lookup that works without embeddings or a live OpenAI key (semantic `get_product_info` needs both) |
117
117
  | Client wants leads/requests emailed to their team instead of a human escalation | `flowiq agent config <org_id> --tool email_request_tool=true`, then set the recipient list in Agents → Tool Library → Email Request to Team (no CLI path for the addresses yet) |
118
118
  | Talk to the live agent safely (no real WhatsApp ever sent) | `flowiq test send <org_id> "hi, do you sell X?"` |
119
+ | Start a test chat from scratch (agent forgets the earlier test messages AND its earlier tool results) | `flowiq test clear <org_id>` (or `flowiq test send <org_id> "…" --clear`) |
119
120
  | **Tell the team what shipped** (the FlowIQ team update email) | `flowiq updates draft` → enrich the JSON (screenshots via `flowiq updates asset`, a *For the team* note per headline) → `flowiq updates preview <file> --open` → `flowiq updates send <file> --test` → `flowiq updates send <file> --yes` |
120
121
  | Can I use `flowiq updates`? | Yes: `status`, `uncovered`, `draft`, `preview` and `send --test` (a copy to yourself) work for everyone. Only the real `send --yes` to the whole team is Matt's; anyone else gets a 403 there |
121
122
  | Which changelog rows has nobody emailed the team about yet? | `flowiq updates status` / `flowiq updates uncovered` — anything left 20h+ goes out automatically at 08:30 SAST as a plain digest |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowapt/flowiq-cli",
3
- "version": "0.9.5",
3
+ "version": "0.9.6",
4
4
  "description": "Command-line tool for FlowIQ staff: round-trip agent prompts, questionnaires, fine-tuning, pin-board tasks, webhooks, templates, agent-updates, chat exports, and live agent testing without ever touching service-role credentials.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -146,7 +146,8 @@ export async function clear(orgId, opts = {}) {
146
146
  let resp;
147
147
  try { resp = await clearConv(orgId, opts.agent); }
148
148
  catch (e) { console.error(`Clear failed: ${e.message}`); process.exit(1); }
149
- console.log(`Cleared web conversation for contact ${resp.contact_id} (history hidden via memory_cutoff; onboarding/disclaimer state NOT reset).`);
149
+ const tools = Number(resp.tools_cleared || 0);
150
+ console.log(`Cleared web conversation for contact ${resp.contact_id} (history hidden via memory_cutoff; ${tools} remembered tool result(s) set aside in more_data.tool_usage_history_cleared; onboarding/disclaimer state NOT reset).`);
150
151
  }
151
152
 
152
153
  // ---------- phase 2: stress + extract ----------
@@ -182,7 +182,9 @@ export async function show(planId, opts = {}) {
182
182
  if (more.slides && typeof more.slides === "object") {
183
183
  for (const [key, slide] of Object.entries(more.slides)) {
184
184
  if (!slide || typeof slide !== "object") continue;
185
- console.log(`\n${key}${slide.triggered_by ? ` (after ${slide.triggered_by})` : ""}`);
185
+ const idx = /^button_(\d+)$/.exec(slide.triggered_by ?? "")?.[1];
186
+ const tapped = idx !== undefined && Array.isArray(more.buttons) ? more.buttons[Number(idx)]?.text : null;
187
+ console.log(`\n${key}${tapped ? ` (sent when "${tapped}" is tapped)` : slide.triggered_by ? ` (after ${slide.triggered_by})` : ""}`);
186
188
  if (slide.message) console.log(indent(slide.message));
187
189
  if (slide.media_url) console.log(` media: ${slide.media_url}`);
188
190
  }
@@ -191,7 +193,11 @@ export async function show(planId, opts = {}) {
191
193
  const buttons = Array.isArray(more.buttons) ? more.buttons : [];
192
194
  if (buttons.length) {
193
195
  console.log("\nButtons");
194
- for (const b of buttons) console.log(` [${b?.type ?? "?"}] ${b?.text ?? ""}${b?.url ? ` → ${b.url}` : ""}`);
196
+ // Marketing plans carry 0-10 buttons: quick_reply, url, phone, copy_code (app src/lib/broadcastPlanButtons.ts).
197
+ for (const b of buttons) {
198
+ const target = b?.url ? ` → ${b.url}` : b?.phone_number ? ` → call ${b.phone_number}` : b?.code ? ` → code ${b.code}` : "";
199
+ console.log(` [${b?.type ?? "?"}] ${b?.text ?? ""}${target}`);
200
+ }
195
201
  }
196
202
 
197
203
  console.log("\nCreative");