@whisperr/wizard 0.1.12 → 0.1.13
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/index.js +82 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -73,7 +73,7 @@ var systemPrompt = `
|
|
|
73
73
|
This SDK is published on pub.dev. Integrate it as follows.
|
|
74
74
|
|
|
75
75
|
1) Dependency. Add to pubspec.yaml under dependencies:
|
|
76
|
-
whisperr: ^0.2.
|
|
76
|
+
whisperr: ^0.2.2
|
|
77
77
|
Then the SDK expects \`flutter pub get\` to be run (run it via bash).
|
|
78
78
|
|
|
79
79
|
2) Initialize once, early, before runApp(), in lib/main.dart:
|
|
@@ -1539,6 +1539,51 @@ async function pollFirstEvent(config, session, opts = {}) {
|
|
|
1539
1539
|
return { received: false };
|
|
1540
1540
|
}
|
|
1541
1541
|
|
|
1542
|
+
// src/core/postflight.ts
|
|
1543
|
+
import { spawn as spawn2 } from "child_process";
|
|
1544
|
+
var MAX_OUTPUT = 4e3;
|
|
1545
|
+
var DEFAULT_TIMEOUT_MS = 18e4;
|
|
1546
|
+
function runVerifyCommand(repoPath, command, opts = {}) {
|
|
1547
|
+
if (!command || !command.trim()) {
|
|
1548
|
+
return Promise.resolve({ ran: false, ok: true, output: "" });
|
|
1549
|
+
}
|
|
1550
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
1551
|
+
return new Promise((resolve2) => {
|
|
1552
|
+
const child = spawn2(command, { cwd: repoPath, shell: true, env: process.env });
|
|
1553
|
+
let out = "";
|
|
1554
|
+
const append = (d) => {
|
|
1555
|
+
out += d.toString();
|
|
1556
|
+
if (out.length > MAX_OUTPUT * 4) out = out.slice(-MAX_OUTPUT * 2);
|
|
1557
|
+
};
|
|
1558
|
+
child.stdout?.on("data", append);
|
|
1559
|
+
child.stderr?.on("data", append);
|
|
1560
|
+
const timer = setTimeout(() => {
|
|
1561
|
+
child.kill("SIGKILL");
|
|
1562
|
+
resolve2({ ran: true, ok: false, command, output: tail(out), timedOut: true });
|
|
1563
|
+
}, timeoutMs);
|
|
1564
|
+
child.on("close", (code) => {
|
|
1565
|
+
clearTimeout(timer);
|
|
1566
|
+
resolve2({
|
|
1567
|
+
ran: true,
|
|
1568
|
+
ok: code === 0,
|
|
1569
|
+
command,
|
|
1570
|
+
exitCode: code,
|
|
1571
|
+
output: tail(out),
|
|
1572
|
+
// 127 = "command not found": the verify tool isn't on PATH here.
|
|
1573
|
+
toolMissing: code === 127
|
|
1574
|
+
});
|
|
1575
|
+
});
|
|
1576
|
+
child.on("error", () => {
|
|
1577
|
+
clearTimeout(timer);
|
|
1578
|
+
resolve2({ ran: true, ok: false, command, output: tail(out), toolMissing: true });
|
|
1579
|
+
});
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
function tail(s) {
|
|
1583
|
+
const t = s.trim();
|
|
1584
|
+
return t.length > MAX_OUTPUT ? `\u2026${t.slice(-MAX_OUTPUT)}` : t;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1542
1587
|
// src/core/report.ts
|
|
1543
1588
|
async function postRunReport(config, session, report) {
|
|
1544
1589
|
if (config.offline) return;
|
|
@@ -1705,6 +1750,40 @@ Flutter is live today; ${theme.bright(
|
|
|
1705
1750
|
return 1;
|
|
1706
1751
|
}
|
|
1707
1752
|
}
|
|
1753
|
+
let verified = null;
|
|
1754
|
+
if (chosen.playbook.verifyCommand && files.length) {
|
|
1755
|
+
const cmd = chosen.playbook.verifyCommand;
|
|
1756
|
+
const vspin = p.spinner();
|
|
1757
|
+
vspin.start(`Verifying the integration \u2014 ${theme.muted(cmd)}`);
|
|
1758
|
+
const verdict = await runVerifyCommand(repoPath, cmd);
|
|
1759
|
+
if (verdict.toolMissing) {
|
|
1760
|
+
vspin.stop(
|
|
1761
|
+
theme.warn("Couldn't verify automatically") + theme.muted(` \u2014 \`${cmd}\` isn't available here. Run it yourself before committing.`)
|
|
1762
|
+
);
|
|
1763
|
+
} else if (verdict.timedOut) {
|
|
1764
|
+
vspin.stop(
|
|
1765
|
+
theme.warn(`Verification timed out \u2014 \`${cmd}\``) + theme.muted(" \u2014 run it yourself before committing.")
|
|
1766
|
+
);
|
|
1767
|
+
} else if (verdict.ok) {
|
|
1768
|
+
verified = true;
|
|
1769
|
+
vspin.stop(theme.success("Verified \u2713") + theme.muted(` (${cmd})`));
|
|
1770
|
+
} else {
|
|
1771
|
+
verified = false;
|
|
1772
|
+
vspin.stop(theme.alert(`Verification failed \u2014 ${cmd}`));
|
|
1773
|
+
if (verdict.output) {
|
|
1774
|
+
p.note(verdict.output, theme.warn("Verifier output"));
|
|
1775
|
+
}
|
|
1776
|
+
const reverted = await maybeRevert(
|
|
1777
|
+
repoPath,
|
|
1778
|
+
checkpoint,
|
|
1779
|
+
"The integration didn't pass its build/lint check, so the edits may be broken."
|
|
1780
|
+
);
|
|
1781
|
+
if (reverted) {
|
|
1782
|
+
p.outro(theme.muted("Reverted \u2014 nothing was left in your working tree."));
|
|
1783
|
+
return 1;
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1708
1787
|
const wiredMap = await scanWiredEvents(
|
|
1709
1788
|
repoPath,
|
|
1710
1789
|
files,
|
|
@@ -1719,6 +1798,7 @@ Flutter is live today; ${theme.bright(
|
|
|
1719
1798
|
target: chosen.playbook.target.id,
|
|
1720
1799
|
repo_fingerprint: fingerprint,
|
|
1721
1800
|
identify_wired: outcome.coreOk,
|
|
1801
|
+
verified,
|
|
1722
1802
|
cost_usd: outcome.costUsd,
|
|
1723
1803
|
duration_ms: outcome.durationMs,
|
|
1724
1804
|
summary: outcome.summary.slice(0, 4e3),
|
|
@@ -1726,7 +1806,7 @@ Flutter is live today; ${theme.bright(
|
|
|
1726
1806
|
});
|
|
1727
1807
|
p.log.info(
|
|
1728
1808
|
theme.muted(
|
|
1729
|
-
`${wiredMap.size}/${manifest.events.length} events wired \xB7 ${files.length} file${files.length === 1 ? "" : "s"} changed \xB7
|
|
1809
|
+
`${wiredMap.size}/${manifest.events.length} events wired \xB7 ${files.length} file${files.length === 1 ? "" : "s"} changed \xB7 ` + (verified === true ? "verified \xB7 " : verified === false ? "unverified \xB7 " : "") + `${Math.round(outcome.durationMs / 1e3)}s`
|
|
1730
1810
|
)
|
|
1731
1811
|
);
|
|
1732
1812
|
if (!config.offline) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whisperr/wizard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "Whisperr Wizard — one command to integrate the Whisperr SDK into your app. Authenticates with your onboarded account and uses an AI coding agent to wire up identify() and your business events automatically.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"private": false,
|