@whisperr/wizard 0.1.12 → 0.1.14
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 +110 -4
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
+
// src/index.ts
|
|
4
|
+
import { readFileSync, realpathSync } from "fs";
|
|
5
|
+
import { dirname, join as join3 } from "path";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
|
|
3
8
|
// src/cli.ts
|
|
4
9
|
import { resolve } from "path";
|
|
5
10
|
import * as p from "@clack/prompts";
|
|
@@ -73,7 +78,7 @@ var systemPrompt = `
|
|
|
73
78
|
This SDK is published on pub.dev. Integrate it as follows.
|
|
74
79
|
|
|
75
80
|
1) Dependency. Add to pubspec.yaml under dependencies:
|
|
76
|
-
whisperr: ^0.2.
|
|
81
|
+
whisperr: ^0.2.2
|
|
77
82
|
Then the SDK expects \`flutter pub get\` to be run (run it via bash).
|
|
78
83
|
|
|
79
84
|
2) Initialize once, early, before runApp(), in lib/main.dart:
|
|
@@ -1539,6 +1544,51 @@ async function pollFirstEvent(config, session, opts = {}) {
|
|
|
1539
1544
|
return { received: false };
|
|
1540
1545
|
}
|
|
1541
1546
|
|
|
1547
|
+
// src/core/postflight.ts
|
|
1548
|
+
import { spawn as spawn2 } from "child_process";
|
|
1549
|
+
var MAX_OUTPUT = 4e3;
|
|
1550
|
+
var DEFAULT_TIMEOUT_MS = 18e4;
|
|
1551
|
+
function runVerifyCommand(repoPath, command, opts = {}) {
|
|
1552
|
+
if (!command || !command.trim()) {
|
|
1553
|
+
return Promise.resolve({ ran: false, ok: true, output: "" });
|
|
1554
|
+
}
|
|
1555
|
+
const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
1556
|
+
return new Promise((resolve2) => {
|
|
1557
|
+
const child = spawn2(command, { cwd: repoPath, shell: true, env: process.env });
|
|
1558
|
+
let out = "";
|
|
1559
|
+
const append = (d) => {
|
|
1560
|
+
out += d.toString();
|
|
1561
|
+
if (out.length > MAX_OUTPUT * 4) out = out.slice(-MAX_OUTPUT * 2);
|
|
1562
|
+
};
|
|
1563
|
+
child.stdout?.on("data", append);
|
|
1564
|
+
child.stderr?.on("data", append);
|
|
1565
|
+
const timer = setTimeout(() => {
|
|
1566
|
+
child.kill("SIGKILL");
|
|
1567
|
+
resolve2({ ran: true, ok: false, command, output: tail(out), timedOut: true });
|
|
1568
|
+
}, timeoutMs);
|
|
1569
|
+
child.on("close", (code) => {
|
|
1570
|
+
clearTimeout(timer);
|
|
1571
|
+
resolve2({
|
|
1572
|
+
ran: true,
|
|
1573
|
+
ok: code === 0,
|
|
1574
|
+
command,
|
|
1575
|
+
exitCode: code,
|
|
1576
|
+
output: tail(out),
|
|
1577
|
+
// 127 = "command not found": the verify tool isn't on PATH here.
|
|
1578
|
+
toolMissing: code === 127
|
|
1579
|
+
});
|
|
1580
|
+
});
|
|
1581
|
+
child.on("error", () => {
|
|
1582
|
+
clearTimeout(timer);
|
|
1583
|
+
resolve2({ ran: true, ok: false, command, output: tail(out), toolMissing: true });
|
|
1584
|
+
});
|
|
1585
|
+
});
|
|
1586
|
+
}
|
|
1587
|
+
function tail(s) {
|
|
1588
|
+
const t = s.trim();
|
|
1589
|
+
return t.length > MAX_OUTPUT ? `\u2026${t.slice(-MAX_OUTPUT)}` : t;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1542
1592
|
// src/core/report.ts
|
|
1543
1593
|
async function postRunReport(config, session, report) {
|
|
1544
1594
|
if (config.offline) return;
|
|
@@ -1705,6 +1755,40 @@ Flutter is live today; ${theme.bright(
|
|
|
1705
1755
|
return 1;
|
|
1706
1756
|
}
|
|
1707
1757
|
}
|
|
1758
|
+
let verified = null;
|
|
1759
|
+
if (chosen.playbook.verifyCommand && files.length) {
|
|
1760
|
+
const cmd = chosen.playbook.verifyCommand;
|
|
1761
|
+
const vspin = p.spinner();
|
|
1762
|
+
vspin.start(`Verifying the integration \u2014 ${theme.muted(cmd)}`);
|
|
1763
|
+
const verdict = await runVerifyCommand(repoPath, cmd);
|
|
1764
|
+
if (verdict.toolMissing) {
|
|
1765
|
+
vspin.stop(
|
|
1766
|
+
theme.warn("Couldn't verify automatically") + theme.muted(` \u2014 \`${cmd}\` isn't available here. Run it yourself before committing.`)
|
|
1767
|
+
);
|
|
1768
|
+
} else if (verdict.timedOut) {
|
|
1769
|
+
vspin.stop(
|
|
1770
|
+
theme.warn(`Verification timed out \u2014 \`${cmd}\``) + theme.muted(" \u2014 run it yourself before committing.")
|
|
1771
|
+
);
|
|
1772
|
+
} else if (verdict.ok) {
|
|
1773
|
+
verified = true;
|
|
1774
|
+
vspin.stop(theme.success("Verified \u2713") + theme.muted(` (${cmd})`));
|
|
1775
|
+
} else {
|
|
1776
|
+
verified = false;
|
|
1777
|
+
vspin.stop(theme.alert(`Verification failed \u2014 ${cmd}`));
|
|
1778
|
+
if (verdict.output) {
|
|
1779
|
+
p.note(verdict.output, theme.warn("Verifier output"));
|
|
1780
|
+
}
|
|
1781
|
+
const reverted = await maybeRevert(
|
|
1782
|
+
repoPath,
|
|
1783
|
+
checkpoint,
|
|
1784
|
+
"The integration didn't pass its build/lint check, so the edits may be broken."
|
|
1785
|
+
);
|
|
1786
|
+
if (reverted) {
|
|
1787
|
+
p.outro(theme.muted("Reverted \u2014 nothing was left in your working tree."));
|
|
1788
|
+
return 1;
|
|
1789
|
+
}
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1708
1792
|
const wiredMap = await scanWiredEvents(
|
|
1709
1793
|
repoPath,
|
|
1710
1794
|
files,
|
|
@@ -1719,6 +1803,7 @@ Flutter is live today; ${theme.bright(
|
|
|
1719
1803
|
target: chosen.playbook.target.id,
|
|
1720
1804
|
repo_fingerprint: fingerprint,
|
|
1721
1805
|
identify_wired: outcome.coreOk,
|
|
1806
|
+
verified,
|
|
1722
1807
|
cost_usd: outcome.costUsd,
|
|
1723
1808
|
duration_ms: outcome.durationMs,
|
|
1724
1809
|
summary: outcome.summary.slice(0, 4e3),
|
|
@@ -1726,7 +1811,7 @@ Flutter is live today; ${theme.bright(
|
|
|
1726
1811
|
});
|
|
1727
1812
|
p.log.info(
|
|
1728
1813
|
theme.muted(
|
|
1729
|
-
`${wiredMap.size}/${manifest.events.length} events wired \xB7 ${files.length} file${files.length === 1 ? "" : "s"} changed \xB7
|
|
1814
|
+
`${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
1815
|
)
|
|
1731
1816
|
);
|
|
1732
1817
|
if (!config.offline) {
|
|
@@ -1859,6 +1944,12 @@ function summarizeManifest(m) {
|
|
|
1859
1944
|
}
|
|
1860
1945
|
|
|
1861
1946
|
// src/index.ts
|
|
1947
|
+
var modulePath = fileURLToPath(import.meta.url);
|
|
1948
|
+
function packageVersion() {
|
|
1949
|
+
const packagePath = join3(dirname(modulePath), "..", "package.json");
|
|
1950
|
+
const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
1951
|
+
return pkg.version ?? "0.0.0";
|
|
1952
|
+
}
|
|
1862
1953
|
function parseArgs(argv) {
|
|
1863
1954
|
const args = [...argv];
|
|
1864
1955
|
const opts = {};
|
|
@@ -1922,7 +2013,7 @@ async function main() {
|
|
|
1922
2013
|
return;
|
|
1923
2014
|
}
|
|
1924
2015
|
if ("version" in parsed) {
|
|
1925
|
-
console.log(
|
|
2016
|
+
console.log(packageVersion());
|
|
1926
2017
|
return;
|
|
1927
2018
|
}
|
|
1928
2019
|
try {
|
|
@@ -1933,4 +2024,19 @@ async function main() {
|
|
|
1933
2024
|
process.exit(1);
|
|
1934
2025
|
}
|
|
1935
2026
|
}
|
|
1936
|
-
|
|
2027
|
+
function isCliEntry() {
|
|
2028
|
+
if (!process.argv[1]) return false;
|
|
2029
|
+
try {
|
|
2030
|
+
return realpathSync(modulePath) === realpathSync(process.argv[1]);
|
|
2031
|
+
} catch {
|
|
2032
|
+
return modulePath === process.argv[1];
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
if (isCliEntry()) {
|
|
2036
|
+
void main();
|
|
2037
|
+
}
|
|
2038
|
+
export {
|
|
2039
|
+
main,
|
|
2040
|
+
packageVersion,
|
|
2041
|
+
parseArgs
|
|
2042
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@whisperr/wizard",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
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,
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"dev": "tsup --watch",
|
|
23
23
|
"start": "node dist/index.js",
|
|
24
24
|
"typecheck": "tsc --noEmit",
|
|
25
|
+
"test": "node --import tsx --test test/*.test.ts",
|
|
25
26
|
"prepublishOnly": "npm run build",
|
|
26
27
|
"dev:local": "tsx src/index.ts"
|
|
27
28
|
},
|