@posthog/wizard 2.12.0 → 2.13.0
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/{AuditChecksViewer-DsfXIO9e.js → AuditChecksViewer-B0J7zcY2.js} +157 -54
- package/dist/AuditChecksViewer-B0J7zcY2.js.map +1 -0
- package/dist/{add-mcp-server-to-clients-BKoew3aT.js → add-mcp-server-to-clients-CUNR00bB.js} +4 -4
- package/dist/{add-mcp-server-to-clients-BKoew3aT.js.map → add-mcp-server-to-clients-CUNR00bB.js.map} +1 -1
- package/dist/{agent-interface-D5W9BAB2.js → agent-interface-CV0-vtxj.js} +7 -6
- package/dist/{agent-interface-D5W9BAB2.js.map → agent-interface-CV0-vtxj.js.map} +1 -1
- package/dist/{agent-runner-B8Cx6X6x.js → agent-runner-LvVQH31D.js} +9 -8
- package/dist/{agent-runner-B8Cx6X6x.js.map → agent-runner-LvVQH31D.js.map} +1 -1
- package/dist/analytics-BH7bEHQR.js +2 -0
- package/dist/{analytics-DmD31Ssc.js → analytics-VM7laaFx.js} +2 -2
- package/dist/{analytics-DmD31Ssc.js.map → analytics-VM7laaFx.js.map} +1 -1
- package/dist/bin.js +237 -32
- package/dist/bin.js.map +1 -1
- package/dist/{debug-I5sRZubJ.js → debug-BdcTB7EF.js} +1 -1
- package/dist/{debug-Bkaqv1ab.js → debug-Cqi6nVfX.js} +2 -2
- package/dist/{debug-Bkaqv1ab.js.map → debug-Cqi6nVfX.js.map} +1 -1
- package/dist/{detection-C_RfYYDe.js → detection-CSjmal-X.js} +3 -3
- package/dist/{detection-C_RfYYDe.js.map → detection-CSjmal-X.js.map} +1 -1
- package/dist/{package-manager-qxP2PpM_.js → package-manager-CD8RQW-e.js} +2 -2
- package/dist/{package-manager-qxP2PpM_.js.map → package-manager-CD8RQW-e.js.map} +1 -1
- package/dist/{posthog-integration-DX77Msto.js → posthog-integration-BL21S3T6.js} +9 -9
- package/dist/{posthog-integration-DX77Msto.js.map → posthog-integration-BL21S3T6.js.map} +1 -1
- package/dist/provisioning-BdQ1ONIg.js +2 -0
- package/dist/{provisioning-DUj285NO.js → provisioning-g9aoVIEd.js} +3 -3
- package/dist/{provisioning-DUj285NO.js.map → provisioning-g9aoVIEd.js.map} +1 -1
- package/dist/{registry-CCtIsqb8.js → registry-BaMEaAKd.js} +4 -4
- package/dist/{registry-CCtIsqb8.js.map → registry-BaMEaAKd.js.map} +1 -1
- package/dist/{router-BTfmEDDJ.js → router-COhhuIW3.js} +3 -2
- package/dist/router-COhhuIW3.js.map +1 -0
- package/dist/{setup-utils-Bv8z6HMb.js → setup-utils-CNV7FSlY.js} +6 -6
- package/dist/{setup-utils-Bv8z6HMb.js.map → setup-utils-CNV7FSlY.js.map} +1 -1
- package/dist/setup-utils-CU4FIqjB.js +2 -0
- package/dist/{start-playground-DYNQ8rOz.js → start-playground-C9GWnVdM.js} +3 -3
- package/dist/{start-playground-DYNQ8rOz.js.map → start-playground-C9GWnVdM.js.map} +1 -1
- package/dist/{start-tui-DleQG3La.js → start-tui-B_zwutLe.js} +1225 -42
- package/dist/start-tui-B_zwutLe.js.map +1 -0
- package/dist/{steps-C-syS8if.js → steps-Dawz7k3T.js} +6 -6
- package/dist/{steps-C-syS8if.js.map → steps-Dawz7k3T.js.map} +1 -1
- package/dist/{telemetry-DHZfjgqx.js → telemetry-D6bjWA-A.js} +2 -2
- package/dist/{telemetry-DHZfjgqx.js.map → telemetry-D6bjWA-A.js.map} +1 -1
- package/dist/{wizard-abort-DfhWuzaw.js → wizard-abort-CJkNkSjT.js} +3 -3
- package/dist/{wizard-abort-DfhWuzaw.js.map → wizard-abort-CJkNkSjT.js.map} +1 -1
- package/dist/{wizard-abort-DIhFXJ5N.js → wizard-abort-Dl0BkqhT.js} +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/dist/AuditChecksViewer-DsfXIO9e.js.map +0 -1
- package/dist/analytics-JDitS2JI.js +0 -2
- package/dist/provisioning-CHfTOEvg.js +0 -2
- package/dist/router-BTfmEDDJ.js.map +0 -1
- package/dist/setup-utils-CoX-vLgw.js +0 -2
- package/dist/start-tui-DleQG3La.js.map +0 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { C as Integration, D as POSTHOG_DOCS_URL, H as getSkillsBaseUrl, N as REMOTE_SKILLS_BASE_URL, R as WIZARD_TOOLS_MENU_FLAG_KEY, f as SIGNUP_WIZARD_READINESS_CONFIG, l as setUI, m as getBlockingServiceKeys, s as logToFile, w as OAUTH_PORTS } from "./debug-
|
|
1
|
+
import { C as Integration, D as POSTHOG_DOCS_URL, H as getSkillsBaseUrl, N as REMOTE_SKILLS_BASE_URL, R as WIZARD_TOOLS_MENU_FLAG_KEY, f as SIGNUP_WIZARD_READINESS_CONFIG, l as setUI, m as getBlockingServiceKeys, s as logToFile, w as OAUTH_PORTS } from "./debug-Cqi6nVfX.js";
|
|
2
2
|
import { a as relativeToInstallDir, n as WIZARD_LOG_FILE } from "./paths-DJS47p5x.js";
|
|
3
|
-
import { n as analytics } from "./analytics-
|
|
4
|
-
import { l as ApiError, p as getUiHostFromHost } from "./setup-utils-
|
|
3
|
+
import { n as analytics } from "./analytics-VM7laaFx.js";
|
|
4
|
+
import { l as ApiError, p as getUiHostFromHost } from "./setup-utils-CNV7FSlY.js";
|
|
5
5
|
import { t as ADDITIONAL_FEATURE_LABELS } from "./wizard-session-BcNJTl2I.js";
|
|
6
|
-
import { r as wizardAbort } from "./wizard-abort-
|
|
7
|
-
import { _ as coerceAuditChecks, d as fetchSkillMenu, g as AUDIT_SEVERITY_STYLE,
|
|
8
|
-
import { t as EVENT_PLAN_FILE } from "./posthog-integration-
|
|
9
|
-
import {
|
|
6
|
+
import { r as wizardAbort } from "./wizard-abort-CJkNkSjT.js";
|
|
7
|
+
import { _ as coerceAuditChecks, d as fetchSkillMenu, g as AUDIT_SEVERITY_STYLE, m as AUDIT_CHECKS_KEY, p as AUDIT_CHECKS_FILE, u as downloadSkill, v as getAuditChecks } from "./agent-interface-CV0-vtxj.js";
|
|
8
|
+
import { t as EVENT_PLAN_FILE } from "./posthog-integration-BL21S3T6.js";
|
|
9
|
+
import { i as fetchHealthIssues, n as getWorkflowConfig, o as POSTHOG_SDKS, s as STRIPE_SDKS } from "./bin.js";
|
|
10
10
|
import { t as ALL_FEATURE_VALUES } from "./defaults-GbLPuHxj.js";
|
|
11
|
-
import { a as getSupportedClients, c as removeMCPServer, i as getInstalledClients, o as getSupportedPluginClients, s as installPlugins, u as isPluginCapable } from "./add-mcp-server-to-clients-
|
|
12
|
-
import "./router-
|
|
13
|
-
import {
|
|
11
|
+
import { a as getSupportedClients, c as removeMCPServer, i as getInstalledClients, o as getSupportedPluginClients, s as installPlugins, u as isPluginCapable } from "./add-mcp-server-to-clients-CUNR00bB.js";
|
|
12
|
+
import "./router-COhhuIW3.js";
|
|
13
|
+
import { E as WizardStore, S as SplitView, T as Icons, _ as useStdoutDimensions, a as SEVERITY_ORDER, b as ProgressList, c as LearnCard, d as ScreenContainer, f as EventPlanViewer, h as ConfirmationInput, i as SEVERITY_LABEL, l as HNViewer, m as ModalOverlay, n as McpScreen, o as ServiceHealthList, p as LogViewer, r as IssueTable, s as TipsCard, t as AuditChecksViewer, u as TabContainer, v as PickerMenu, w as Colors, x as LoadingBox, y as useKeyBindings } from "./AuditChecksViewer-B0J7zcY2.js";
|
|
14
14
|
import { spawn, spawnSync } from "node:child_process";
|
|
15
15
|
import { join } from "node:path";
|
|
16
16
|
import * as fs$1 from "fs";
|
|
@@ -913,7 +913,7 @@ const FrameworkPicker = ({ store, onComplete }) => {
|
|
|
913
913
|
})),
|
|
914
914
|
onSelect: (value) => {
|
|
915
915
|
const integration = Array.isArray(value) ? value[0] : value;
|
|
916
|
-
import("./registry-
|
|
916
|
+
import("./registry-BaMEaAKd.js").then((n) => n.n).then(({ FRAMEWORK_REGISTRY }) => {
|
|
917
917
|
const config = FRAMEWORK_REGISTRY[integration];
|
|
918
918
|
store.setFrameworkConfig(integration, config);
|
|
919
919
|
store.setDetectedFramework(config.metadata.name);
|
|
@@ -1827,21 +1827,22 @@ const CaptureVisual = () => /* @__PURE__ */ jsxs(VisualBox, { children: [
|
|
|
1827
1827
|
})
|
|
1828
1828
|
] })
|
|
1829
1829
|
] });
|
|
1830
|
+
const EventCaptureSlide = {
|
|
1831
|
+
area: "Event Capture",
|
|
1832
|
+
intro: [
|
|
1833
|
+
"Everything you do in PostHog starts with event captures. Every dashboard, insight, funnel, cohort, and replay is built on top of events.",
|
|
1834
|
+
"We're checking that your project's event capture calls cover key user actions and use sensible event names, so you can build high-quality insights and reports.",
|
|
1835
|
+
"We're also checking that you use a reverse proxy so your events are not blocked by ad blockers or tracking blockers."
|
|
1836
|
+
],
|
|
1837
|
+
visual: /* @__PURE__ */ jsx(CaptureVisual, {}),
|
|
1838
|
+
docsUrl: "https://posthog.com/docs/product-analytics/capture-events"
|
|
1839
|
+
};
|
|
1830
1840
|
//#endregion
|
|
1831
1841
|
//#region src/ui/tui/screens/audit/slides/index.ts
|
|
1832
1842
|
const AUDIT_AREA_SLIDES = [
|
|
1833
1843
|
InstallationSlide,
|
|
1834
1844
|
IdentificationSlide,
|
|
1835
|
-
|
|
1836
|
-
area: "Event Capture",
|
|
1837
|
-
intro: [
|
|
1838
|
-
"Everything you do in PostHog starts with event captures. Every dashboard, insight, funnel, cohort, and replay is built on top of events.",
|
|
1839
|
-
"We're checking that your project's event capture calls cover key user actions and use sensible event names, so you can build high-quality insights and reports.",
|
|
1840
|
-
"We're also checking that you use a reverse proxy so your events are not blocked by ad blockers or tracking blockers."
|
|
1841
|
-
],
|
|
1842
|
-
visual: /* @__PURE__ */ jsx(CaptureVisual, {}),
|
|
1843
|
-
docsUrl: "https://posthog.com/docs/product-analytics/capture-events"
|
|
1844
|
-
}
|
|
1845
|
+
EventCaptureSlide
|
|
1845
1846
|
];
|
|
1846
1847
|
//#endregion
|
|
1847
1848
|
//#region src/ui/tui/screens/audit/AuditAreaPane.tsx
|
|
@@ -1859,18 +1860,18 @@ const AUDIT_AREA_SLIDES = [
|
|
|
1859
1860
|
*
|
|
1860
1861
|
* Pressing `O` opens the active slide's docs URL.
|
|
1861
1862
|
*/
|
|
1862
|
-
const FINDING_STATUSES = [
|
|
1863
|
+
const FINDING_STATUSES$1 = [
|
|
1863
1864
|
"error",
|
|
1864
1865
|
"warning",
|
|
1865
1866
|
"suggestion"
|
|
1866
1867
|
];
|
|
1867
|
-
const isFinding = (c) => FINDING_STATUSES.includes(c.status);
|
|
1868
|
-
const fallbackSlide = (area) => ({
|
|
1868
|
+
const isFinding$1 = (c) => FINDING_STATUSES$1.includes(c.status);
|
|
1869
|
+
const fallbackSlide$1 = (area) => ({
|
|
1869
1870
|
area,
|
|
1870
1871
|
intro: [`Verifying ${area.toLowerCase()}…`],
|
|
1871
1872
|
docsUrl: ""
|
|
1872
1873
|
});
|
|
1873
|
-
const openLink = (url) => {
|
|
1874
|
+
const openLink$1 = (url) => {
|
|
1874
1875
|
spawn(process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open", process.platform === "win32" ? [
|
|
1875
1876
|
"/c",
|
|
1876
1877
|
"start",
|
|
@@ -1883,18 +1884,18 @@ const openLink = (url) => {
|
|
|
1883
1884
|
};
|
|
1884
1885
|
const AuditAreaPane = ({ checks, reportPath }) => {
|
|
1885
1886
|
const activeArea = checks.filter((c) => c.status === "pending")[0]?.area;
|
|
1886
|
-
const slide = activeArea ? AUDIT_AREA_SLIDES.find((s) => s.area === activeArea) ?? fallbackSlide(activeArea) : null;
|
|
1887
|
+
const slide = activeArea ? AUDIT_AREA_SLIDES.find((s) => s.area === activeArea) ?? fallbackSlide$1(activeArea) : null;
|
|
1887
1888
|
useInput((input) => {
|
|
1888
|
-
if (input.toLowerCase() === "o" && slide?.docsUrl) openLink(slide.docsUrl);
|
|
1889
|
+
if (input.toLowerCase() === "o" && slide?.docsUrl) openLink$1(slide.docsUrl);
|
|
1889
1890
|
});
|
|
1890
|
-
if (slide) return /* @__PURE__ */ jsx(ActiveSlide, {
|
|
1891
|
+
if (slide) return /* @__PURE__ */ jsx(ActiveSlide$1, {
|
|
1891
1892
|
slide,
|
|
1892
|
-
hasFindings: checks.some(isFinding)
|
|
1893
|
+
hasFindings: checks.some(isFinding$1)
|
|
1893
1894
|
});
|
|
1894
1895
|
if (checks.length === 0) return null;
|
|
1895
|
-
return /* @__PURE__ */ jsx(WritingReport, { reportPath });
|
|
1896
|
+
return /* @__PURE__ */ jsx(WritingReport$1, { reportPath });
|
|
1896
1897
|
};
|
|
1897
|
-
const ActiveSlide = ({ slide, hasFindings }) => /* @__PURE__ */ jsxs(Box, {
|
|
1898
|
+
const ActiveSlide$1 = ({ slide, hasFindings }) => /* @__PURE__ */ jsxs(Box, {
|
|
1898
1899
|
flexDirection: "column",
|
|
1899
1900
|
paddingX: 1,
|
|
1900
1901
|
children: [
|
|
@@ -1930,7 +1931,7 @@ const ActiveSlide = ({ slide, hasFindings }) => /* @__PURE__ */ jsxs(Box, {
|
|
|
1930
1931
|
})
|
|
1931
1932
|
]
|
|
1932
1933
|
});
|
|
1933
|
-
const WritingReport = ({ reportPath }) => /* @__PURE__ */ jsxs(Box, {
|
|
1934
|
+
const WritingReport$1 = ({ reportPath }) => /* @__PURE__ */ jsxs(Box, {
|
|
1934
1935
|
flexDirection: "column",
|
|
1935
1936
|
paddingX: 1,
|
|
1936
1937
|
children: [
|
|
@@ -1959,7 +1960,7 @@ const WritingReport = ({ reportPath }) => /* @__PURE__ */ jsxs(Box, {
|
|
|
1959
1960
|
});
|
|
1960
1961
|
//#endregion
|
|
1961
1962
|
//#region src/ui/tui/screens/audit/PendingChecksList.tsx
|
|
1962
|
-
function groupByArea(checks) {
|
|
1963
|
+
function groupByArea$1(checks) {
|
|
1963
1964
|
const order = [];
|
|
1964
1965
|
const map = /* @__PURE__ */ new Map();
|
|
1965
1966
|
for (const c of checks) {
|
|
@@ -1974,7 +1975,7 @@ function groupByArea(checks) {
|
|
|
1974
1975
|
checks: map.get(area)
|
|
1975
1976
|
}));
|
|
1976
1977
|
}
|
|
1977
|
-
function groupIcon(group) {
|
|
1978
|
+
function groupIcon$1(group) {
|
|
1978
1979
|
const total = group.checks.length;
|
|
1979
1980
|
const complete = group.checks.filter((c) => c.status !== "pending").length;
|
|
1980
1981
|
if (complete === 0) return {
|
|
@@ -1990,10 +1991,10 @@ function groupIcon(group) {
|
|
|
1990
1991
|
color: Colors.primary
|
|
1991
1992
|
};
|
|
1992
1993
|
}
|
|
1993
|
-
const GroupHeader = ({ group, showIcon, isActive }) => {
|
|
1994
|
+
const GroupHeader$1 = ({ group, showIcon, isActive }) => {
|
|
1994
1995
|
const complete = group.checks.filter((c) => c.status !== "pending").length;
|
|
1995
1996
|
const total = group.checks.length;
|
|
1996
|
-
const { icon, color } = groupIcon(group);
|
|
1997
|
+
const { icon, color } = groupIcon$1(group);
|
|
1997
1998
|
return /* @__PURE__ */ jsxs(Box, { children: [isActive ? /* @__PURE__ */ jsx(Box, {
|
|
1998
1999
|
marginRight: 1,
|
|
1999
2000
|
children: /* @__PURE__ */ jsx(Spinner, {})
|
|
@@ -2042,7 +2043,7 @@ const PendingChecksList = ({ checks }) => {
|
|
|
2042
2043
|
/* @__PURE__ */ jsx(LoadingBox, { message: "Seeding audit checklist..." })
|
|
2043
2044
|
]
|
|
2044
2045
|
});
|
|
2045
|
-
const groups = groupByArea(checks);
|
|
2046
|
+
const groups = groupByArea$1(checks);
|
|
2046
2047
|
const activeIndex = groups.findIndex((g) => g.checks.some((c) => c.status === "pending"));
|
|
2047
2048
|
return /* @__PURE__ */ jsxs(Box, {
|
|
2048
2049
|
flexDirection: "column",
|
|
@@ -2052,14 +2053,14 @@ const PendingChecksList = ({ checks }) => {
|
|
|
2052
2053
|
children: "Checks"
|
|
2053
2054
|
}),
|
|
2054
2055
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
2055
|
-
termRows < COLLAPSE_BELOW_ROWS ? groups.map((group, i) => /* @__PURE__ */ jsx(GroupHeader, {
|
|
2056
|
+
termRows < COLLAPSE_BELOW_ROWS ? groups.map((group, i) => /* @__PURE__ */ jsx(GroupHeader$1, {
|
|
2056
2057
|
group,
|
|
2057
2058
|
showIcon: true,
|
|
2058
2059
|
isActive: i === activeIndex
|
|
2059
2060
|
}, group.area)) : groups.map((group, i) => /* @__PURE__ */ jsxs(Box, {
|
|
2060
2061
|
flexDirection: "column",
|
|
2061
2062
|
marginTop: i === 0 ? 0 : 1,
|
|
2062
|
-
children: [/* @__PURE__ */ jsx(GroupHeader, {
|
|
2063
|
+
children: [/* @__PURE__ */ jsx(GroupHeader$1, {
|
|
2063
2064
|
group,
|
|
2064
2065
|
showIcon: false,
|
|
2065
2066
|
isActive: i === activeIndex
|
|
@@ -2076,7 +2077,7 @@ const AuditRunScreen = ({ store }) => {
|
|
|
2076
2077
|
const statuses = store.statusMessages.length > 0 ? store.statusMessages : void 0;
|
|
2077
2078
|
const [columns] = useStdoutDimensions();
|
|
2078
2079
|
const checks = getAuditChecks(store.session);
|
|
2079
|
-
const reportPath = `./${
|
|
2080
|
+
const reportPath = `./${getWorkflowConfig(store.router.activeFlow)?.reportFile ?? "posthog-audit-report.md"}`;
|
|
2080
2081
|
const pendingChecksList = /* @__PURE__ */ jsx(PendingChecksList, { checks });
|
|
2081
2082
|
return /* @__PURE__ */ jsx(TabContainer, {
|
|
2082
2083
|
tabs: [
|
|
@@ -2202,7 +2203,8 @@ const AuditChecksOutroSection = ({ checks, installDir }) => {
|
|
|
2202
2203
|
/**
|
|
2203
2204
|
* AuditOutroScreen — Audit-specific post-run summary. Renders the standard
|
|
2204
2205
|
* success / error / cancel views with the audit checks summary inlined into
|
|
2205
|
-
* the success body. The report path
|
|
2206
|
+
* the success body. The report path shown in the success headline comes from
|
|
2207
|
+
* the workflow's `successMessage`, so this screen is workflow-agnostic.
|
|
2206
2208
|
*/
|
|
2207
2209
|
const AuditOutroScreen = ({ store }) => {
|
|
2208
2210
|
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
@@ -2230,6 +2232,22 @@ const AuditOutroScreen = ({ store }) => {
|
|
|
2230
2232
|
bold: true,
|
|
2231
2233
|
children: ["✔ ", outroData.message || "Audit complete!"]
|
|
2232
2234
|
}),
|
|
2235
|
+
outroData.reportFile && /* @__PURE__ */ jsxs(Box, {
|
|
2236
|
+
flexDirection: "column",
|
|
2237
|
+
marginTop: 1,
|
|
2238
|
+
children: [
|
|
2239
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2240
|
+
color: "cyan",
|
|
2241
|
+
bold: true,
|
|
2242
|
+
children: "Report saved to:"
|
|
2243
|
+
}),
|
|
2244
|
+
/* @__PURE__ */ jsx(Text, { children: join(store.session.installDir, outroData.reportFile) }),
|
|
2245
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2246
|
+
dimColor: true,
|
|
2247
|
+
children: "A markdown file in your project folder — open it in any editor to read the full audit."
|
|
2248
|
+
})
|
|
2249
|
+
]
|
|
2250
|
+
}),
|
|
2233
2251
|
/* @__PURE__ */ jsx(AuditChecksOutroSection, {
|
|
2234
2252
|
checks: getAuditChecks(store.session),
|
|
2235
2253
|
installDir: store.session.installDir
|
|
@@ -2272,6 +2290,1168 @@ const AuditOutroScreen = ({ store }) => {
|
|
|
2272
2290
|
});
|
|
2273
2291
|
};
|
|
2274
2292
|
//#endregion
|
|
2293
|
+
//#region src/ui/tui/screens/audit-3000/arcade-colors.ts
|
|
2294
|
+
const NEON_PINK$2 = "#F54E00";
|
|
2295
|
+
const NEON_BLUE$2 = "#1D4AFF";
|
|
2296
|
+
const NEON_GOLD$2 = "#F9BD2B";
|
|
2297
|
+
//#endregion
|
|
2298
|
+
//#region src/ui/tui/screens/audit-3000/Audit3000IntroScreen.tsx
|
|
2299
|
+
const AUDIT3000_SKILL_ID = "audit-3000";
|
|
2300
|
+
const ArcadeBanner = () => {
|
|
2301
|
+
const [blinkOn, setBlinkOn] = useState(true);
|
|
2302
|
+
useEffect(() => {
|
|
2303
|
+
const id = setInterval(() => setBlinkOn((v) => !v), 600);
|
|
2304
|
+
return () => clearInterval(id);
|
|
2305
|
+
}, []);
|
|
2306
|
+
const top = "┏" + "━".repeat(32) + "┓";
|
|
2307
|
+
const bottom = "┗" + "━".repeat(32) + "┛";
|
|
2308
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
2309
|
+
flexDirection: "column",
|
|
2310
|
+
alignItems: "center",
|
|
2311
|
+
children: [
|
|
2312
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2313
|
+
bold: true,
|
|
2314
|
+
color: NEON_PINK$2,
|
|
2315
|
+
children: top
|
|
2316
|
+
}),
|
|
2317
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2318
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2319
|
+
bold: true,
|
|
2320
|
+
color: NEON_PINK$2,
|
|
2321
|
+
children: "┃"
|
|
2322
|
+
}),
|
|
2323
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2324
|
+
bold: true,
|
|
2325
|
+
color: NEON_GOLD$2,
|
|
2326
|
+
children: " A U D I T "
|
|
2327
|
+
}),
|
|
2328
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2329
|
+
bold: true,
|
|
2330
|
+
color: NEON_BLUE$2,
|
|
2331
|
+
children: "-"
|
|
2332
|
+
}),
|
|
2333
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2334
|
+
bold: true,
|
|
2335
|
+
color: NEON_GOLD$2,
|
|
2336
|
+
children: " 3 0 0 0 "
|
|
2337
|
+
}),
|
|
2338
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2339
|
+
bold: true,
|
|
2340
|
+
color: NEON_PINK$2,
|
|
2341
|
+
children: "┃"
|
|
2342
|
+
})
|
|
2343
|
+
] }),
|
|
2344
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2345
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2346
|
+
bold: true,
|
|
2347
|
+
color: NEON_PINK$2,
|
|
2348
|
+
children: "┃"
|
|
2349
|
+
}),
|
|
2350
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2351
|
+
dimColor: !blinkOn,
|
|
2352
|
+
color: NEON_BLUE$2,
|
|
2353
|
+
children: " ▶ INSERT COIN TO PLAY ◀ "
|
|
2354
|
+
}),
|
|
2355
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2356
|
+
bold: true,
|
|
2357
|
+
color: NEON_PINK$2,
|
|
2358
|
+
children: "┃"
|
|
2359
|
+
})
|
|
2360
|
+
] }),
|
|
2361
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2362
|
+
bold: true,
|
|
2363
|
+
color: NEON_PINK$2,
|
|
2364
|
+
children: bottom
|
|
2365
|
+
})
|
|
2366
|
+
]
|
|
2367
|
+
});
|
|
2368
|
+
};
|
|
2369
|
+
const Audit3000IntroScreen = ({ store }) => {
|
|
2370
|
+
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
2371
|
+
const [showingMoreInfo, setShowingMoreInfo] = useState(false);
|
|
2372
|
+
const { session } = store;
|
|
2373
|
+
const { skillEntry, fetchFailed } = useSkillEntry(AUDIT3000_SKILL_ID, session.localMcp);
|
|
2374
|
+
const body = showingMoreInfo ? /* @__PURE__ */ jsxs(Box, {
|
|
2375
|
+
flexDirection: "column",
|
|
2376
|
+
width: 56,
|
|
2377
|
+
children: [
|
|
2378
|
+
/* @__PURE__ */ jsx(Box, {
|
|
2379
|
+
marginBottom: 1,
|
|
2380
|
+
children: /* @__PURE__ */ jsxs(Text, { children: ["The wizard is an agent that executes PostHog tasks. Its code is open source: ", /* @__PURE__ */ jsx(Text, {
|
|
2381
|
+
color: "cyan",
|
|
2382
|
+
children: "https://github.com/PostHog/wizard"
|
|
2383
|
+
})] })
|
|
2384
|
+
}),
|
|
2385
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2386
|
+
"The",
|
|
2387
|
+
" ",
|
|
2388
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2389
|
+
color: "cyan",
|
|
2390
|
+
italic: true,
|
|
2391
|
+
children: AUDIT3000_SKILL_ID
|
|
2392
|
+
}),
|
|
2393
|
+
" ",
|
|
2394
|
+
"workflow reviews your PostHog integration across 34 checks — SDK install, identification, event capture, event quality, stale feature flag hygiene, session replay (fix + optimize), and use-case expansion across 8 PostHog products. When enrichment is available it also produces a company profile and use-case match. Nothing in your project is modified."
|
|
2395
|
+
] }),
|
|
2396
|
+
/* @__PURE__ */ jsx(Box, {
|
|
2397
|
+
marginTop: 1,
|
|
2398
|
+
children: /* @__PURE__ */ jsxs(Text, { children: [
|
|
2399
|
+
"Results stream live to the",
|
|
2400
|
+
" ",
|
|
2401
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2402
|
+
color: "cyan",
|
|
2403
|
+
bold: true,
|
|
2404
|
+
children: "Hi-score Table"
|
|
2405
|
+
}),
|
|
2406
|
+
" ",
|
|
2407
|
+
"tab during the run — that's your live report. When the audit finishes, the same report is also exported to",
|
|
2408
|
+
" ",
|
|
2409
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2410
|
+
color: "cyan",
|
|
2411
|
+
children: "./posthog-audit-3000-report.md"
|
|
2412
|
+
}),
|
|
2413
|
+
" in your project folder."
|
|
2414
|
+
] })
|
|
2415
|
+
}),
|
|
2416
|
+
/* @__PURE__ */ jsx(Box, {
|
|
2417
|
+
marginTop: 1,
|
|
2418
|
+
children: /* @__PURE__ */ jsx(SkillSourceInfo, {
|
|
2419
|
+
skillId: AUDIT3000_SKILL_ID,
|
|
2420
|
+
skillEntry,
|
|
2421
|
+
fetchFailed
|
|
2422
|
+
})
|
|
2423
|
+
})
|
|
2424
|
+
]
|
|
2425
|
+
}) : /* @__PURE__ */ jsxs(Box, {
|
|
2426
|
+
flexDirection: "column",
|
|
2427
|
+
alignItems: "center",
|
|
2428
|
+
children: [/* @__PURE__ */ jsx(ArcadeBanner, {}), /* @__PURE__ */ jsxs(Box, {
|
|
2429
|
+
marginTop: 1,
|
|
2430
|
+
flexDirection: "column",
|
|
2431
|
+
alignItems: "center",
|
|
2432
|
+
children: [
|
|
2433
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2434
|
+
bold: true,
|
|
2435
|
+
children: "34 checks. 9 levels. 1 final report."
|
|
2436
|
+
}),
|
|
2437
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2438
|
+
dimColor: true,
|
|
2439
|
+
children: "High-score your PostHog integration before the boss fight."
|
|
2440
|
+
}),
|
|
2441
|
+
/* @__PURE__ */ jsx(Box, {
|
|
2442
|
+
marginTop: 1,
|
|
2443
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
2444
|
+
dimColor: true,
|
|
2445
|
+
children: [
|
|
2446
|
+
"Live report: ",
|
|
2447
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2448
|
+
color: NEON_GOLD$2,
|
|
2449
|
+
children: "Hi-score Table"
|
|
2450
|
+
}),
|
|
2451
|
+
" tab · Export: ./posthog-audit-3000-report.md"
|
|
2452
|
+
]
|
|
2453
|
+
})
|
|
2454
|
+
})
|
|
2455
|
+
]
|
|
2456
|
+
})]
|
|
2457
|
+
});
|
|
2458
|
+
const menuOptions = showingMoreInfo ? [{
|
|
2459
|
+
label: "Back",
|
|
2460
|
+
value: "back"
|
|
2461
|
+
}] : [
|
|
2462
|
+
{
|
|
2463
|
+
label: "PRESS START",
|
|
2464
|
+
value: "continue"
|
|
2465
|
+
},
|
|
2466
|
+
{
|
|
2467
|
+
label: "More info",
|
|
2468
|
+
value: "more-info"
|
|
2469
|
+
},
|
|
2470
|
+
{
|
|
2471
|
+
label: "Cancel",
|
|
2472
|
+
value: "cancel"
|
|
2473
|
+
}
|
|
2474
|
+
];
|
|
2475
|
+
const handleSelect = (value) => {
|
|
2476
|
+
if (value === "cancel") process.exit(0);
|
|
2477
|
+
else if (value === "more-info") setShowingMoreInfo(true);
|
|
2478
|
+
else if (value === "back") setShowingMoreInfo(false);
|
|
2479
|
+
else store.completeSetup();
|
|
2480
|
+
};
|
|
2481
|
+
return /* @__PURE__ */ jsx(IntroScreenLayout, {
|
|
2482
|
+
installDir: session.installDir,
|
|
2483
|
+
body,
|
|
2484
|
+
showDetection: !showingMoreInfo,
|
|
2485
|
+
workflowLabel: session.workflowLabel,
|
|
2486
|
+
skillId: session.skillId,
|
|
2487
|
+
menuOptions,
|
|
2488
|
+
onSelect: handleSelect
|
|
2489
|
+
});
|
|
2490
|
+
};
|
|
2491
|
+
//#endregion
|
|
2492
|
+
//#region src/ui/tui/screens/audit-3000/slides/eventQuality.tsx
|
|
2493
|
+
const EventQualityVisual = () => /* @__PURE__ */ jsxs(VisualBox, { children: [
|
|
2494
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
2495
|
+
color: "green",
|
|
2496
|
+
children: "event_clicked "
|
|
2497
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
2498
|
+
color: "green",
|
|
2499
|
+
children: "✓"
|
|
2500
|
+
})] }),
|
|
2501
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
2502
|
+
color: "yellow",
|
|
2503
|
+
children: "eventClicked "
|
|
2504
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
2505
|
+
color: "yellow",
|
|
2506
|
+
children: "~ duplicate?"
|
|
2507
|
+
})] }),
|
|
2508
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
2509
|
+
color: "yellow",
|
|
2510
|
+
children: "click_event "
|
|
2511
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
2512
|
+
color: "yellow",
|
|
2513
|
+
children: "~ duplicate?"
|
|
2514
|
+
})] }),
|
|
2515
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
2516
|
+
color: "red",
|
|
2517
|
+
children: "big_kitchen_sink "
|
|
2518
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
2519
|
+
color: "red",
|
|
2520
|
+
children: "✗ 22 props"
|
|
2521
|
+
})] })
|
|
2522
|
+
] });
|
|
2523
|
+
const EventQualitySlide = {
|
|
2524
|
+
area: "Event Quality",
|
|
2525
|
+
intro: [
|
|
2526
|
+
"LEVEL 5: EVENT QUALITY. The capture call-sites are clean. The events themselves are the real boss fight.",
|
|
2527
|
+
"Scanning for: naming inconsistencies, semantic duplicates, kitchen-sink event payloads, and (if your PostHog project is linked) which captured events actually drive insights and dashboards.",
|
|
2528
|
+
"4 subagents fan out in parallel. The ticker shows them clearing checks live."
|
|
2529
|
+
],
|
|
2530
|
+
visual: /* @__PURE__ */ jsx(EventQualityVisual, {}),
|
|
2531
|
+
docsUrl: "https://posthog.com/docs/product-analytics/best-practices"
|
|
2532
|
+
};
|
|
2533
|
+
//#endregion
|
|
2534
|
+
//#region src/ui/tui/screens/audit-3000/slides/featureFlags.tsx
|
|
2535
|
+
const FeatureFlagsVisual = () => /* @__PURE__ */ jsxs(VisualBox, { children: [
|
|
2536
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2537
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2538
|
+
color: "red",
|
|
2539
|
+
children: "new-checkout-v2 "
|
|
2540
|
+
}),
|
|
2541
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2542
|
+
dimColor: true,
|
|
2543
|
+
children: "no code refs "
|
|
2544
|
+
}),
|
|
2545
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2546
|
+
color: "red",
|
|
2547
|
+
children: "DROP"
|
|
2548
|
+
})
|
|
2549
|
+
] }),
|
|
2550
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2551
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2552
|
+
color: "yellow",
|
|
2553
|
+
children: "beta-dashboard "
|
|
2554
|
+
}),
|
|
2555
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2556
|
+
dimColor: true,
|
|
2557
|
+
children: "1 ref, 100% on "
|
|
2558
|
+
}),
|
|
2559
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2560
|
+
color: "yellow",
|
|
2561
|
+
children: "REVIEW"
|
|
2562
|
+
})
|
|
2563
|
+
] }),
|
|
2564
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2565
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2566
|
+
color: "green",
|
|
2567
|
+
children: "killswitch-payments"
|
|
2568
|
+
}),
|
|
2569
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2570
|
+
dimColor: true,
|
|
2571
|
+
children: "live experiment"
|
|
2572
|
+
}),
|
|
2573
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2574
|
+
color: "green",
|
|
2575
|
+
children: "KEEP"
|
|
2576
|
+
})
|
|
2577
|
+
] })
|
|
2578
|
+
] });
|
|
2579
|
+
const FeatureFlagsSlide = {
|
|
2580
|
+
area: "Feature Flags",
|
|
2581
|
+
intro: [
|
|
2582
|
+
"LEVEL 6: STALE FLAGS. Old flags add evaluation overhead and confuse the next engineer who wonders if a flag is still live.",
|
|
2583
|
+
"Cross-referencing PostHog's stale-flag classification against your source tree. Each flag scored: safe-to-disable, needs-review, or unknown.",
|
|
2584
|
+
"The final report ships with a copy-paste cleanup prompt. We never touch a flag."
|
|
2585
|
+
],
|
|
2586
|
+
visual: /* @__PURE__ */ jsx(FeatureFlagsVisual, {}),
|
|
2587
|
+
docsUrl: "https://posthog.com/docs/feature-flags"
|
|
2588
|
+
};
|
|
2589
|
+
//#endregion
|
|
2590
|
+
//#region src/ui/tui/screens/audit-3000/slides/expansion.tsx
|
|
2591
|
+
const ExpansionVisual = () => /* @__PURE__ */ jsxs(VisualBox, { children: [
|
|
2592
|
+
/* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
2593
|
+
color: "cyan",
|
|
2594
|
+
children: "product analytics "
|
|
2595
|
+
}), /* @__PURE__ */ jsx(Text, {
|
|
2596
|
+
color: "green",
|
|
2597
|
+
children: "■■■■■"
|
|
2598
|
+
})] }),
|
|
2599
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2600
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2601
|
+
color: "cyan",
|
|
2602
|
+
children: "error tracking "
|
|
2603
|
+
}),
|
|
2604
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2605
|
+
color: "red",
|
|
2606
|
+
children: "□□□□□"
|
|
2607
|
+
}),
|
|
2608
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2609
|
+
dimColor: true,
|
|
2610
|
+
children: " sentry detected"
|
|
2611
|
+
})
|
|
2612
|
+
] }),
|
|
2613
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2614
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2615
|
+
color: "cyan",
|
|
2616
|
+
children: "session replay "
|
|
2617
|
+
}),
|
|
2618
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2619
|
+
color: "yellow",
|
|
2620
|
+
children: "■■□□□"
|
|
2621
|
+
}),
|
|
2622
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2623
|
+
dimColor: true,
|
|
2624
|
+
children: " partial"
|
|
2625
|
+
})
|
|
2626
|
+
] }),
|
|
2627
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2628
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2629
|
+
color: "cyan",
|
|
2630
|
+
children: "llm observability "
|
|
2631
|
+
}),
|
|
2632
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2633
|
+
color: "red",
|
|
2634
|
+
children: "□□□□□"
|
|
2635
|
+
}),
|
|
2636
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2637
|
+
dimColor: true,
|
|
2638
|
+
children: " greenfield"
|
|
2639
|
+
})
|
|
2640
|
+
] })
|
|
2641
|
+
] });
|
|
2642
|
+
//#endregion
|
|
2643
|
+
//#region src/ui/tui/screens/audit-3000/slides/index.ts
|
|
2644
|
+
const AUDIT_3000_AREA_SLIDES = [
|
|
2645
|
+
InstallationSlide,
|
|
2646
|
+
IdentificationSlide,
|
|
2647
|
+
EventCaptureSlide,
|
|
2648
|
+
EventQualitySlide,
|
|
2649
|
+
FeatureFlagsSlide,
|
|
2650
|
+
{
|
|
2651
|
+
area: "Use Case: Expansion",
|
|
2652
|
+
intro: [
|
|
2653
|
+
"BONUS ROUND: EXPANSION. You might be paying for tools PostHog covers natively.",
|
|
2654
|
+
"Scanning for competitive SDKs (Sentry, LaunchDarkly, Mixpanel, Datadog, OpenTelemetry, GA4) and PostHog coverage gaps across 8 product surfaces.",
|
|
2655
|
+
"8 subagents in two waves of 4. Each one returns one of: cross-sell, greenfield, gap, or pass."
|
|
2656
|
+
],
|
|
2657
|
+
visual: /* @__PURE__ */ jsx(ExpansionVisual, {}),
|
|
2658
|
+
docsUrl: "https://posthog.com/docs"
|
|
2659
|
+
}
|
|
2660
|
+
];
|
|
2661
|
+
//#endregion
|
|
2662
|
+
//#region src/ui/tui/screens/audit-3000/Audit3000AreaPane.tsx
|
|
2663
|
+
/**
|
|
2664
|
+
* Audit-3000 right pane — arcade-flavoured fork of `AuditAreaPane`.
|
|
2665
|
+
*
|
|
2666
|
+
* Mirrors the audit pane's three-state logic (active slide → empty →
|
|
2667
|
+
* wrap-up) but routes through the audit-3000 slide registry and uses
|
|
2668
|
+
* "LEVEL N: <area>" framing instead of "Verifying ...".
|
|
2669
|
+
*/
|
|
2670
|
+
const FINDING_STATUSES = [
|
|
2671
|
+
"error",
|
|
2672
|
+
"warning",
|
|
2673
|
+
"suggestion"
|
|
2674
|
+
];
|
|
2675
|
+
const isFinding = (c) => FINDING_STATUSES.includes(c.status);
|
|
2676
|
+
const fallbackSlide = (area) => ({
|
|
2677
|
+
area,
|
|
2678
|
+
intro: [`Now playing: ${area.toLowerCase()}\u2026`],
|
|
2679
|
+
docsUrl: ""
|
|
2680
|
+
});
|
|
2681
|
+
const openLink = (url) => {
|
|
2682
|
+
spawn(process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open", process.platform === "win32" ? [
|
|
2683
|
+
"/c",
|
|
2684
|
+
"start",
|
|
2685
|
+
"",
|
|
2686
|
+
url
|
|
2687
|
+
] : [url], {
|
|
2688
|
+
detached: true,
|
|
2689
|
+
stdio: "ignore"
|
|
2690
|
+
}).unref();
|
|
2691
|
+
};
|
|
2692
|
+
const Audit3000AreaPane = ({ checks, reportPath }) => {
|
|
2693
|
+
const activeArea = checks.filter((c) => c.status === "pending")[0]?.area;
|
|
2694
|
+
const slide = activeArea ? AUDIT_3000_AREA_SLIDES.find((s) => s.area === activeArea) ?? fallbackSlide(activeArea) : null;
|
|
2695
|
+
const levelIndex = activeArea ? AUDIT_3000_AREA_SLIDES.findIndex((s) => s.area === activeArea) : -1;
|
|
2696
|
+
const level = levelIndex >= 0 ? levelIndex + 1 : null;
|
|
2697
|
+
useInput((input) => {
|
|
2698
|
+
if (input.toLowerCase() === "o" && slide?.docsUrl) openLink(slide.docsUrl);
|
|
2699
|
+
});
|
|
2700
|
+
if (slide) return /* @__PURE__ */ jsx(ActiveSlide, {
|
|
2701
|
+
slide,
|
|
2702
|
+
level,
|
|
2703
|
+
hasFindings: checks.some(isFinding)
|
|
2704
|
+
});
|
|
2705
|
+
if (checks.length === 0) return null;
|
|
2706
|
+
return /* @__PURE__ */ jsx(WritingReport, { reportPath });
|
|
2707
|
+
};
|
|
2708
|
+
const ActiveSlide = ({ slide, level, hasFindings }) => /* @__PURE__ */ jsxs(Box, {
|
|
2709
|
+
flexDirection: "column",
|
|
2710
|
+
paddingX: 1,
|
|
2711
|
+
children: [
|
|
2712
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2713
|
+
bold: true,
|
|
2714
|
+
color: Colors.accent,
|
|
2715
|
+
children: [level ? `LEVEL ${level}: ` : "", slide.area.toUpperCase()]
|
|
2716
|
+
}),
|
|
2717
|
+
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
2718
|
+
slide.visual,
|
|
2719
|
+
slide.intro.map((paragraph, i) => /* @__PURE__ */ jsxs(Fragment, { children: [i > 0 && /* @__PURE__ */ jsx(Box, { height: 1 }), /* @__PURE__ */ jsx(Text, { children: paragraph })] }, i)),
|
|
2720
|
+
/* @__PURE__ */ jsx(Box, {
|
|
2721
|
+
marginTop: 1,
|
|
2722
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
2723
|
+
dimColor: true,
|
|
2724
|
+
children: [slide.docsUrl && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2725
|
+
"[",
|
|
2726
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2727
|
+
color: Colors.accent,
|
|
2728
|
+
children: "O"
|
|
2729
|
+
}),
|
|
2730
|
+
"] Learn more"
|
|
2731
|
+
] }), hasFindings && /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2732
|
+
slide.docsUrl && " ",
|
|
2733
|
+
"[",
|
|
2734
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2735
|
+
color: Colors.accent,
|
|
2736
|
+
children: "→"
|
|
2737
|
+
}),
|
|
2738
|
+
"] View issues"
|
|
2739
|
+
] })]
|
|
2740
|
+
})
|
|
2741
|
+
})
|
|
2742
|
+
]
|
|
2743
|
+
});
|
|
2744
|
+
const WritingReport = ({ reportPath }) => /* @__PURE__ */ jsxs(Box, {
|
|
2745
|
+
flexDirection: "column",
|
|
2746
|
+
paddingX: 1,
|
|
2747
|
+
children: [
|
|
2748
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2749
|
+
bold: true,
|
|
2750
|
+
color: Colors.accent,
|
|
2751
|
+
children: "STAGE CLEAR."
|
|
2752
|
+
}),
|
|
2753
|
+
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
2754
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
2755
|
+
"All checks resolved. Compiling your high-score reel at",
|
|
2756
|
+
" ",
|
|
2757
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2758
|
+
color: "cyan",
|
|
2759
|
+
children: reportPath
|
|
2760
|
+
}),
|
|
2761
|
+
"."
|
|
2762
|
+
] }),
|
|
2763
|
+
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
2764
|
+
/* @__PURE__ */ jsx(Text, { children: "The report covers everything we checked, what we found, and what to do next." }),
|
|
2765
|
+
/* @__PURE__ */ jsx(Box, { height: 1 }),
|
|
2766
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2767
|
+
dimColor: true,
|
|
2768
|
+
children: "Stand by…"
|
|
2769
|
+
})
|
|
2770
|
+
]
|
|
2771
|
+
});
|
|
2772
|
+
//#endregion
|
|
2773
|
+
//#region src/ui/tui/screens/audit-3000/Audit3000ChecksPanel.tsx
|
|
2774
|
+
/**
|
|
2775
|
+
* Audit-3000 left pane on the Run screen. Arcade-flavoured fork of the
|
|
2776
|
+
* audit workflow's `PendingChecksList`: a running score banner sits on
|
|
2777
|
+
* top, then the area-level "level" headers underneath.
|
|
2778
|
+
*
|
|
2779
|
+
* Per-check rows are deliberately omitted here — the Hi-score Table tab
|
|
2780
|
+
* has the full check-by-check breakdown. This pane is the at-a-glance
|
|
2781
|
+
* stage overview.
|
|
2782
|
+
*/
|
|
2783
|
+
const NEON_PINK$1 = "#F54E00";
|
|
2784
|
+
const NEON_GOLD$1 = "#F9BD2B";
|
|
2785
|
+
const NEON_BLUE$1 = "#1D4AFF";
|
|
2786
|
+
function groupByArea(checks) {
|
|
2787
|
+
const order = [];
|
|
2788
|
+
const map = /* @__PURE__ */ new Map();
|
|
2789
|
+
for (const c of checks) {
|
|
2790
|
+
if (!map.has(c.area)) {
|
|
2791
|
+
map.set(c.area, []);
|
|
2792
|
+
order.push(c.area);
|
|
2793
|
+
}
|
|
2794
|
+
map.get(c.area).push(c);
|
|
2795
|
+
}
|
|
2796
|
+
return order.map((area) => ({
|
|
2797
|
+
area,
|
|
2798
|
+
checks: map.get(area)
|
|
2799
|
+
}));
|
|
2800
|
+
}
|
|
2801
|
+
function countByStatus$1(checks) {
|
|
2802
|
+
const counts = {
|
|
2803
|
+
pending: 0,
|
|
2804
|
+
pass: 0,
|
|
2805
|
+
error: 0,
|
|
2806
|
+
warning: 0,
|
|
2807
|
+
suggestion: 0
|
|
2808
|
+
};
|
|
2809
|
+
for (const c of checks) counts[c.status] += 1;
|
|
2810
|
+
return counts;
|
|
2811
|
+
}
|
|
2812
|
+
const ScoreBanner = ({ checks }) => {
|
|
2813
|
+
const counts = countByStatus$1(checks);
|
|
2814
|
+
const resolved = checks.length - counts.pending;
|
|
2815
|
+
const issues = counts.error + counts.warning + counts.suggestion;
|
|
2816
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
2817
|
+
flexDirection: "column",
|
|
2818
|
+
marginBottom: 1,
|
|
2819
|
+
children: [/* @__PURE__ */ jsxs(Text, { children: [
|
|
2820
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2821
|
+
bold: true,
|
|
2822
|
+
color: NEON_PINK$1,
|
|
2823
|
+
children: "SCORE "
|
|
2824
|
+
}),
|
|
2825
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2826
|
+
bold: true,
|
|
2827
|
+
color: NEON_GOLD$1,
|
|
2828
|
+
children: resolved.toString().padStart(2, "0")
|
|
2829
|
+
}),
|
|
2830
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2831
|
+
dimColor: true,
|
|
2832
|
+
children: " / "
|
|
2833
|
+
}),
|
|
2834
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2835
|
+
bold: true,
|
|
2836
|
+
children: checks.length.toString().padStart(2, "0")
|
|
2837
|
+
})
|
|
2838
|
+
] }), /* @__PURE__ */ jsxs(Text, { children: [
|
|
2839
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2840
|
+
color: "green",
|
|
2841
|
+
children: `PASS \u25B2 ${counts.pass}`
|
|
2842
|
+
}),
|
|
2843
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
2844
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2845
|
+
color: NEON_PINK$1,
|
|
2846
|
+
children: `MISS \u25BC ${issues}`
|
|
2847
|
+
}),
|
|
2848
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
2849
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2850
|
+
dimColor: true,
|
|
2851
|
+
children: `QUEUE \u25CB ${counts.pending}`
|
|
2852
|
+
})
|
|
2853
|
+
] })]
|
|
2854
|
+
});
|
|
2855
|
+
};
|
|
2856
|
+
function groupIcon(group) {
|
|
2857
|
+
const total = group.checks.length;
|
|
2858
|
+
const complete = group.checks.filter((c) => c.status !== "pending").length;
|
|
2859
|
+
if (complete === 0) return {
|
|
2860
|
+
icon: Icons.squareOpen,
|
|
2861
|
+
color: Colors.muted
|
|
2862
|
+
};
|
|
2863
|
+
if (complete === total) return {
|
|
2864
|
+
icon: Icons.squareFilled,
|
|
2865
|
+
color: Colors.success
|
|
2866
|
+
};
|
|
2867
|
+
return {
|
|
2868
|
+
icon: Icons.triangleRight,
|
|
2869
|
+
color: Colors.primary
|
|
2870
|
+
};
|
|
2871
|
+
}
|
|
2872
|
+
const GroupHeader = ({ group, level, showIcon, isActive }) => {
|
|
2873
|
+
const complete = group.checks.filter((c) => c.status !== "pending").length;
|
|
2874
|
+
const total = group.checks.length;
|
|
2875
|
+
const { icon, color } = groupIcon(group);
|
|
2876
|
+
return /* @__PURE__ */ jsxs(Box, { children: [isActive ? /* @__PURE__ */ jsx(Box, {
|
|
2877
|
+
marginRight: 1,
|
|
2878
|
+
children: /* @__PURE__ */ jsx(Spinner, {})
|
|
2879
|
+
}) : showIcon ? /* @__PURE__ */ jsxs(Text, { children: [/* @__PURE__ */ jsx(Text, {
|
|
2880
|
+
color,
|
|
2881
|
+
children: icon
|
|
2882
|
+
}), " "] }) : null, /* @__PURE__ */ jsxs(Text, { children: [
|
|
2883
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2884
|
+
color: NEON_BLUE$1,
|
|
2885
|
+
bold: true,
|
|
2886
|
+
children: `L${level} `
|
|
2887
|
+
}),
|
|
2888
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2889
|
+
bold: true,
|
|
2890
|
+
children: group.area
|
|
2891
|
+
}),
|
|
2892
|
+
" ",
|
|
2893
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
2894
|
+
dimColor: true,
|
|
2895
|
+
children: [
|
|
2896
|
+
"(",
|
|
2897
|
+
complete,
|
|
2898
|
+
"/",
|
|
2899
|
+
total,
|
|
2900
|
+
")"
|
|
2901
|
+
]
|
|
2902
|
+
})
|
|
2903
|
+
] })] });
|
|
2904
|
+
};
|
|
2905
|
+
const Audit3000ChecksPanel = ({ checks }) => {
|
|
2906
|
+
if (checks.length === 0) return /* @__PURE__ */ jsxs(Box, {
|
|
2907
|
+
flexDirection: "column",
|
|
2908
|
+
children: [
|
|
2909
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2910
|
+
bold: true,
|
|
2911
|
+
children: "AUDIT-3000"
|
|
2912
|
+
}),
|
|
2913
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
2914
|
+
/* @__PURE__ */ jsx(LoadingBox, { message: "Booting up arcade cabinet..." })
|
|
2915
|
+
]
|
|
2916
|
+
});
|
|
2917
|
+
const groups = groupByArea(checks);
|
|
2918
|
+
const activeIndex = groups.findIndex((g) => g.checks.some((c) => c.status === "pending"));
|
|
2919
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
2920
|
+
flexDirection: "column",
|
|
2921
|
+
children: [
|
|
2922
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2923
|
+
bold: true,
|
|
2924
|
+
color: NEON_PINK$1,
|
|
2925
|
+
children: "AUDIT-3000"
|
|
2926
|
+
}),
|
|
2927
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
2928
|
+
/* @__PURE__ */ jsx(ScoreBanner, { checks }),
|
|
2929
|
+
groups.map((group, i) => /* @__PURE__ */ jsx(GroupHeader, {
|
|
2930
|
+
group,
|
|
2931
|
+
level: i + 1,
|
|
2932
|
+
showIcon: true,
|
|
2933
|
+
isActive: i === activeIndex
|
|
2934
|
+
}, group.area)),
|
|
2935
|
+
/* @__PURE__ */ jsx(Box, {
|
|
2936
|
+
marginTop: 1,
|
|
2937
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
2938
|
+
dimColor: true,
|
|
2939
|
+
children: [
|
|
2940
|
+
"Full breakdown: ",
|
|
2941
|
+
/* @__PURE__ */ jsx(Text, {
|
|
2942
|
+
color: NEON_GOLD$1,
|
|
2943
|
+
children: "Hi-score table (report)"
|
|
2944
|
+
}),
|
|
2945
|
+
" ",
|
|
2946
|
+
"tab"
|
|
2947
|
+
]
|
|
2948
|
+
})
|
|
2949
|
+
})
|
|
2950
|
+
]
|
|
2951
|
+
});
|
|
2952
|
+
};
|
|
2953
|
+
function nextRandom(seed) {
|
|
2954
|
+
let t = seed + 1831565813 >>> 0;
|
|
2955
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
2956
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
2957
|
+
return {
|
|
2958
|
+
value: ((t ^ t >>> 14) >>> 0) / 4294967296,
|
|
2959
|
+
nextSeed: t >>> 0
|
|
2960
|
+
};
|
|
2961
|
+
}
|
|
2962
|
+
function randomInt(seed, min, max) {
|
|
2963
|
+
const { value, nextSeed } = nextRandom(seed);
|
|
2964
|
+
return {
|
|
2965
|
+
value: min + Math.floor(value * (max - min + 1)),
|
|
2966
|
+
nextSeed
|
|
2967
|
+
};
|
|
2968
|
+
}
|
|
2969
|
+
function initialState(hiScore = 0, rngSeed = 1) {
|
|
2970
|
+
return {
|
|
2971
|
+
hedgehogState: "grounded",
|
|
2972
|
+
hedgehogRow: 2,
|
|
2973
|
+
jumpFramesRemaining: 0,
|
|
2974
|
+
obstacles: [],
|
|
2975
|
+
score: 0,
|
|
2976
|
+
hiScore,
|
|
2977
|
+
isGameOver: false,
|
|
2978
|
+
tick: 0,
|
|
2979
|
+
ticksUntilNextSpawn: 6,
|
|
2980
|
+
rngSeed
|
|
2981
|
+
};
|
|
2982
|
+
}
|
|
2983
|
+
function jump(state) {
|
|
2984
|
+
if (state.isGameOver) return state;
|
|
2985
|
+
if (state.hedgehogState !== "grounded") return state;
|
|
2986
|
+
return {
|
|
2987
|
+
...state,
|
|
2988
|
+
hedgehogState: "jumping",
|
|
2989
|
+
hedgehogRow: 1,
|
|
2990
|
+
jumpFramesRemaining: 8
|
|
2991
|
+
};
|
|
2992
|
+
}
|
|
2993
|
+
function restart(state) {
|
|
2994
|
+
return initialState(state.hiScore, state.rngSeed);
|
|
2995
|
+
}
|
|
2996
|
+
function tick(state) {
|
|
2997
|
+
if (state.isGameOver) return state;
|
|
2998
|
+
let { hedgehogState, hedgehogRow, jumpFramesRemaining } = state;
|
|
2999
|
+
if (hedgehogState === "jumping") {
|
|
3000
|
+
jumpFramesRemaining -= 1;
|
|
3001
|
+
if (jumpFramesRemaining <= 0) {
|
|
3002
|
+
hedgehogState = "grounded";
|
|
3003
|
+
hedgehogRow = 2;
|
|
3004
|
+
jumpFramesRemaining = 0;
|
|
3005
|
+
}
|
|
3006
|
+
}
|
|
3007
|
+
const movedObstacles = [];
|
|
3008
|
+
let scoreDelta = 1;
|
|
3009
|
+
let hit = false;
|
|
3010
|
+
for (const obs of state.obstacles) {
|
|
3011
|
+
const next = {
|
|
3012
|
+
...obs,
|
|
3013
|
+
x: obs.x - 1
|
|
3014
|
+
};
|
|
3015
|
+
if (next.x < 0) continue;
|
|
3016
|
+
if (next.x === 4 && next.row === hedgehogRow) {
|
|
3017
|
+
if (next.kind === "spike") {
|
|
3018
|
+
hit = true;
|
|
3019
|
+
movedObstacles.push(next);
|
|
3020
|
+
continue;
|
|
3021
|
+
}
|
|
3022
|
+
scoreDelta += 5;
|
|
3023
|
+
continue;
|
|
3024
|
+
}
|
|
3025
|
+
movedObstacles.push(next);
|
|
3026
|
+
}
|
|
3027
|
+
let rngSeed = state.rngSeed;
|
|
3028
|
+
let ticksUntilNextSpawn = state.ticksUntilNextSpawn - 1;
|
|
3029
|
+
if (ticksUntilNextSpawn <= 0) {
|
|
3030
|
+
const kindRoll = nextRandom(rngSeed);
|
|
3031
|
+
rngSeed = kindRoll.nextSeed;
|
|
3032
|
+
const kind = kindRoll.value < .65 ? "spike" : "ring";
|
|
3033
|
+
const row = kind === "spike" ? 2 : 1;
|
|
3034
|
+
movedObstacles.push({
|
|
3035
|
+
kind,
|
|
3036
|
+
x: 39,
|
|
3037
|
+
row
|
|
3038
|
+
});
|
|
3039
|
+
const cooldown = randomInt(rngSeed, 6, 14);
|
|
3040
|
+
rngSeed = cooldown.nextSeed;
|
|
3041
|
+
ticksUntilNextSpawn = cooldown.value;
|
|
3042
|
+
}
|
|
3043
|
+
const score = state.score + scoreDelta;
|
|
3044
|
+
const isGameOver = hit;
|
|
3045
|
+
const hiScore = isGameOver ? Math.max(state.hiScore, score) : state.hiScore;
|
|
3046
|
+
return {
|
|
3047
|
+
hedgehogState,
|
|
3048
|
+
hedgehogRow,
|
|
3049
|
+
jumpFramesRemaining,
|
|
3050
|
+
obstacles: movedObstacles,
|
|
3051
|
+
score,
|
|
3052
|
+
hiScore,
|
|
3053
|
+
isGameOver,
|
|
3054
|
+
tick: state.tick + 1,
|
|
3055
|
+
ticksUntilNextSpawn,
|
|
3056
|
+
rngSeed
|
|
3057
|
+
};
|
|
3058
|
+
}
|
|
3059
|
+
//#endregion
|
|
3060
|
+
//#region src/ui/tui/screens/audit-3000/HedgehogRunner.tsx
|
|
3061
|
+
/**
|
|
3062
|
+
* HedgehogRunner — playable arcade game shown while the audit runs.
|
|
3063
|
+
*
|
|
3064
|
+
* Game state lives in the parent (Audit3000RunScreen) so it survives tab
|
|
3065
|
+
* switches. This component owns the render loop (setInterval) and key
|
|
3066
|
+
* bindings; when the user switches tabs the component unmounts, the
|
|
3067
|
+
* interval clears, and state freezes in the parent — free pause behaviour.
|
|
3068
|
+
*/
|
|
3069
|
+
const TICK_MS = 150;
|
|
3070
|
+
const PLAYFIELD_ROWS = 3;
|
|
3071
|
+
const MIN_TERMINAL_COLUMNS = 50;
|
|
3072
|
+
const HEDGEHOG_GLYPH = "O";
|
|
3073
|
+
const SPIKE_GLYPH = "^";
|
|
3074
|
+
const RING_GLYPH = "o";
|
|
3075
|
+
const GROUND_GLYPH = "=";
|
|
3076
|
+
const pad4 = (n) => String(n).padStart(4, "0");
|
|
3077
|
+
const HedgehogRunner = ({ state, onChange }) => {
|
|
3078
|
+
const [columns] = useStdoutDimensions();
|
|
3079
|
+
useEffect(() => {
|
|
3080
|
+
const id = setInterval(() => {
|
|
3081
|
+
onChange((prev) => tick(prev));
|
|
3082
|
+
}, TICK_MS);
|
|
3083
|
+
return () => clearInterval(id);
|
|
3084
|
+
}, [onChange]);
|
|
3085
|
+
useKeyBindings("hedgehog-runner", [{
|
|
3086
|
+
match: "space",
|
|
3087
|
+
label: "space",
|
|
3088
|
+
action: "jump",
|
|
3089
|
+
handler: () => onChange((prev) => jump(prev))
|
|
3090
|
+
}, {
|
|
3091
|
+
match: "r",
|
|
3092
|
+
label: "r",
|
|
3093
|
+
action: "restart",
|
|
3094
|
+
handler: () => onChange((prev) => prev.isGameOver ? restart(prev) : prev)
|
|
3095
|
+
}]);
|
|
3096
|
+
if (columns < MIN_TERMINAL_COLUMNS) return /* @__PURE__ */ jsx(Box, {
|
|
3097
|
+
flexDirection: "column",
|
|
3098
|
+
paddingX: 1,
|
|
3099
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
3100
|
+
dimColor: true,
|
|
3101
|
+
children: [
|
|
3102
|
+
"Widen the terminal to at least ",
|
|
3103
|
+
MIN_TERMINAL_COLUMNS,
|
|
3104
|
+
" columns to play Hedgehog Runner."
|
|
3105
|
+
]
|
|
3106
|
+
})
|
|
3107
|
+
});
|
|
3108
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
3109
|
+
flexDirection: "column",
|
|
3110
|
+
paddingX: 1,
|
|
3111
|
+
children: [
|
|
3112
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
3113
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
3114
|
+
bold: true,
|
|
3115
|
+
color: NEON_BLUE$2,
|
|
3116
|
+
children: ["SCORE ", pad4(state.score)]
|
|
3117
|
+
}),
|
|
3118
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
3119
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
3120
|
+
bold: true,
|
|
3121
|
+
color: NEON_GOLD$2,
|
|
3122
|
+
children: ["HI ", pad4(state.hiScore)]
|
|
3123
|
+
}),
|
|
3124
|
+
state.isGameOver && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(Text, { children: " " }), /* @__PURE__ */ jsx(Text, {
|
|
3125
|
+
bold: true,
|
|
3126
|
+
color: "red",
|
|
3127
|
+
children: "✱ GAME OVER ✱"
|
|
3128
|
+
})] })
|
|
3129
|
+
] }),
|
|
3130
|
+
Array.from({ length: PLAYFIELD_ROWS }, (_, row) => /* @__PURE__ */ jsx(PlayfieldRow, {
|
|
3131
|
+
row,
|
|
3132
|
+
state
|
|
3133
|
+
}, row)),
|
|
3134
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3135
|
+
color: Colors.muted,
|
|
3136
|
+
children: GROUND_GLYPH.repeat(40)
|
|
3137
|
+
})
|
|
3138
|
+
]
|
|
3139
|
+
});
|
|
3140
|
+
};
|
|
3141
|
+
const PlayfieldRow = ({ row, state }) => {
|
|
3142
|
+
const cells = [];
|
|
3143
|
+
for (let x = 0; x < 40; x++) {
|
|
3144
|
+
if (x === 4 && row === state.hedgehogRow) {
|
|
3145
|
+
cells.push({
|
|
3146
|
+
ch: HEDGEHOG_GLYPH,
|
|
3147
|
+
color: NEON_PINK$2,
|
|
3148
|
+
bold: true
|
|
3149
|
+
});
|
|
3150
|
+
continue;
|
|
3151
|
+
}
|
|
3152
|
+
const obstacle = state.obstacles.find((o) => o.x === x && o.row === row);
|
|
3153
|
+
if (obstacle) {
|
|
3154
|
+
cells.push(obstacle.kind === "spike" ? {
|
|
3155
|
+
ch: SPIKE_GLYPH,
|
|
3156
|
+
color: "red",
|
|
3157
|
+
bold: true
|
|
3158
|
+
} : {
|
|
3159
|
+
ch: RING_GLYPH,
|
|
3160
|
+
color: NEON_GOLD$2,
|
|
3161
|
+
bold: true
|
|
3162
|
+
});
|
|
3163
|
+
continue;
|
|
3164
|
+
}
|
|
3165
|
+
cells.push({ ch: " " });
|
|
3166
|
+
}
|
|
3167
|
+
return /* @__PURE__ */ jsx(Text, { children: cells.map((c, i) => /* @__PURE__ */ jsx(Fragment, { children: c.color ? /* @__PURE__ */ jsx(Text, {
|
|
3168
|
+
color: c.color,
|
|
3169
|
+
bold: c.bold,
|
|
3170
|
+
children: c.ch
|
|
3171
|
+
}) : c.ch }, i)) });
|
|
3172
|
+
};
|
|
3173
|
+
//#endregion
|
|
3174
|
+
//#region src/ui/tui/screens/audit-3000/Audit3000RunScreen.tsx
|
|
3175
|
+
const AUDIT_3000_REPORT_FILE_FALLBACK = "posthog-audit-3000-report.md";
|
|
3176
|
+
const Audit3000RunScreen = ({ store }) => {
|
|
3177
|
+
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
3178
|
+
useFileWatcher(join(store.session.installDir, AUDIT_CHECKS_FILE), (parsed) => store.setFrameworkContext(AUDIT_CHECKS_KEY, coerceAuditChecks(parsed)));
|
|
3179
|
+
const statuses = store.statusMessages.length > 0 ? store.statusMessages : void 0;
|
|
3180
|
+
const [columns] = useStdoutDimensions();
|
|
3181
|
+
const [gameState, setGameState] = useState(() => initialState());
|
|
3182
|
+
const checks = getAuditChecks(store.session);
|
|
3183
|
+
const reportPath = `./${getWorkflowConfig(store.router.activeFlow)?.reportFile ?? AUDIT_3000_REPORT_FILE_FALLBACK}`;
|
|
3184
|
+
const checksPanel = /* @__PURE__ */ jsx(Audit3000ChecksPanel, { checks });
|
|
3185
|
+
return /* @__PURE__ */ jsx(TabContainer, {
|
|
3186
|
+
tabs: [
|
|
3187
|
+
{
|
|
3188
|
+
id: "status",
|
|
3189
|
+
label: "Arcade",
|
|
3190
|
+
component: columns < 80 ? /* @__PURE__ */ jsx(Box, {
|
|
3191
|
+
flexDirection: "column",
|
|
3192
|
+
flexGrow: 1,
|
|
3193
|
+
children: checksPanel
|
|
3194
|
+
}) : /* @__PURE__ */ jsx(SplitView, {
|
|
3195
|
+
left: /* @__PURE__ */ jsx(Audit3000AreaPane, {
|
|
3196
|
+
checks,
|
|
3197
|
+
reportPath
|
|
3198
|
+
}),
|
|
3199
|
+
right: checksPanel
|
|
3200
|
+
})
|
|
3201
|
+
},
|
|
3202
|
+
{
|
|
3203
|
+
id: "audit-checks",
|
|
3204
|
+
label: "Hi-score table (report)",
|
|
3205
|
+
component: /* @__PURE__ */ jsx(AuditChecksViewer, { checks })
|
|
3206
|
+
},
|
|
3207
|
+
{
|
|
3208
|
+
id: "play",
|
|
3209
|
+
label: "Play",
|
|
3210
|
+
component: /* @__PURE__ */ jsx(HedgehogRunner, {
|
|
3211
|
+
state: gameState,
|
|
3212
|
+
onChange: setGameState
|
|
3213
|
+
})
|
|
3214
|
+
},
|
|
3215
|
+
{
|
|
3216
|
+
id: "logs",
|
|
3217
|
+
label: "Tail logs",
|
|
3218
|
+
component: /* @__PURE__ */ jsx(LogViewer, { filePath: WIZARD_LOG_FILE })
|
|
3219
|
+
},
|
|
3220
|
+
{
|
|
3221
|
+
id: "hn",
|
|
3222
|
+
label: "HN",
|
|
3223
|
+
component: /* @__PURE__ */ jsx(HNViewer, {})
|
|
3224
|
+
}
|
|
3225
|
+
],
|
|
3226
|
+
statusMessage: statuses,
|
|
3227
|
+
expandableStatus: true,
|
|
3228
|
+
store
|
|
3229
|
+
});
|
|
3230
|
+
};
|
|
3231
|
+
//#endregion
|
|
3232
|
+
//#region src/ui/tui/screens/audit-3000/Audit3000OutroScreen.tsx
|
|
3233
|
+
/**
|
|
3234
|
+
* Audit3000OutroScreen — high-score-style summary after a v3000 audit run.
|
|
3235
|
+
*
|
|
3236
|
+
* On success: arcade FINAL SCORE banner with pass / miss tallies, the
|
|
3237
|
+
* absolute report path, and the standard problematic-items list.
|
|
3238
|
+
*
|
|
3239
|
+
* Error and cancel branches mirror `AuditOutroScreen` so failure modes
|
|
3240
|
+
* stay legible without arcade dressing.
|
|
3241
|
+
*/
|
|
3242
|
+
const NEON_PINK = "#F54E00";
|
|
3243
|
+
const NEON_GOLD = "#F9BD2B";
|
|
3244
|
+
const NEON_BLUE = "#1D4AFF";
|
|
3245
|
+
const PANEL_WIDTH = 48;
|
|
3246
|
+
const padCenter = (s, width) => {
|
|
3247
|
+
if (s.length >= width) return s;
|
|
3248
|
+
const total = width - s.length;
|
|
3249
|
+
const left = Math.floor(total / 2);
|
|
3250
|
+
const right = total - left;
|
|
3251
|
+
return " ".repeat(left) + s + " ".repeat(right);
|
|
3252
|
+
};
|
|
3253
|
+
function countByStatus(checks) {
|
|
3254
|
+
const counts = {
|
|
3255
|
+
pending: 0,
|
|
3256
|
+
pass: 0,
|
|
3257
|
+
error: 0,
|
|
3258
|
+
warning: 0,
|
|
3259
|
+
suggestion: 0
|
|
3260
|
+
};
|
|
3261
|
+
for (const c of checks) counts[c.status] += 1;
|
|
3262
|
+
return counts;
|
|
3263
|
+
}
|
|
3264
|
+
const FinalScorePanel = ({ checks }) => {
|
|
3265
|
+
const counts = countByStatus(checks);
|
|
3266
|
+
const resolved = checks.length - counts.pending;
|
|
3267
|
+
const issues = counts.error + counts.warning + counts.suggestion;
|
|
3268
|
+
const top = "┏" + "━".repeat(PANEL_WIDTH) + "┓";
|
|
3269
|
+
const bottom = "┗" + "━".repeat(PANEL_WIDTH) + "┛";
|
|
3270
|
+
const sep = "┠" + "─".repeat(PANEL_WIDTH) + "┨";
|
|
3271
|
+
const row = (content) => /* @__PURE__ */ jsxs(Text, { children: [
|
|
3272
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3273
|
+
bold: true,
|
|
3274
|
+
color: NEON_PINK,
|
|
3275
|
+
children: "┃"
|
|
3276
|
+
}),
|
|
3277
|
+
/* @__PURE__ */ jsx(Text, { children: content }),
|
|
3278
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3279
|
+
bold: true,
|
|
3280
|
+
color: NEON_PINK,
|
|
3281
|
+
children: "┃"
|
|
3282
|
+
})
|
|
3283
|
+
] });
|
|
3284
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
3285
|
+
flexDirection: "column",
|
|
3286
|
+
marginTop: 1,
|
|
3287
|
+
children: [
|
|
3288
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3289
|
+
bold: true,
|
|
3290
|
+
color: NEON_PINK,
|
|
3291
|
+
children: top
|
|
3292
|
+
}),
|
|
3293
|
+
row(padCenter("GAME OVER", PANEL_WIDTH)),
|
|
3294
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3295
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3296
|
+
bold: true,
|
|
3297
|
+
color: NEON_PINK,
|
|
3298
|
+
children: "┃"
|
|
3299
|
+
}),
|
|
3300
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3301
|
+
color: NEON_GOLD,
|
|
3302
|
+
children: padCenter(`FINAL SCORE ${resolved} / ${checks.length}`, PANEL_WIDTH)
|
|
3303
|
+
}),
|
|
3304
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3305
|
+
bold: true,
|
|
3306
|
+
color: NEON_PINK,
|
|
3307
|
+
children: "┃"
|
|
3308
|
+
})
|
|
3309
|
+
] }),
|
|
3310
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3311
|
+
color: NEON_PINK,
|
|
3312
|
+
children: sep
|
|
3313
|
+
}),
|
|
3314
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3315
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3316
|
+
bold: true,
|
|
3317
|
+
color: NEON_PINK,
|
|
3318
|
+
children: "┃"
|
|
3319
|
+
}),
|
|
3320
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3321
|
+
color: "green",
|
|
3322
|
+
children: padCenter(`PASS \u25B2 ${counts.pass}`, PANEL_WIDTH)
|
|
3323
|
+
}),
|
|
3324
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3325
|
+
bold: true,
|
|
3326
|
+
color: NEON_PINK,
|
|
3327
|
+
children: "┃"
|
|
3328
|
+
})
|
|
3329
|
+
] }),
|
|
3330
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
3331
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3332
|
+
bold: true,
|
|
3333
|
+
color: NEON_PINK,
|
|
3334
|
+
children: "┃"
|
|
3335
|
+
}),
|
|
3336
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3337
|
+
color: NEON_BLUE,
|
|
3338
|
+
children: padCenter(`MISS \u25BC ${issues}`, PANEL_WIDTH)
|
|
3339
|
+
}),
|
|
3340
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3341
|
+
bold: true,
|
|
3342
|
+
color: NEON_PINK,
|
|
3343
|
+
children: "┃"
|
|
3344
|
+
})
|
|
3345
|
+
] }),
|
|
3346
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3347
|
+
bold: true,
|
|
3348
|
+
color: NEON_PINK,
|
|
3349
|
+
children: bottom
|
|
3350
|
+
})
|
|
3351
|
+
]
|
|
3352
|
+
});
|
|
3353
|
+
};
|
|
3354
|
+
const Audit3000OutroScreen = ({ store }) => {
|
|
3355
|
+
useSyncExternalStore((cb) => store.subscribe(cb), () => store.getSnapshot());
|
|
3356
|
+
useInput(() => {
|
|
3357
|
+
store.setOutroDismissed();
|
|
3358
|
+
});
|
|
3359
|
+
const outroData = store.session.outroData;
|
|
3360
|
+
if (!outroData) return /* @__PURE__ */ jsx(Box, {
|
|
3361
|
+
flexDirection: "column",
|
|
3362
|
+
flexGrow: 1,
|
|
3363
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
3364
|
+
dimColor: true,
|
|
3365
|
+
children: "Counting your tokens…"
|
|
3366
|
+
})
|
|
3367
|
+
});
|
|
3368
|
+
const checks = getAuditChecks(store.session);
|
|
3369
|
+
return /* @__PURE__ */ jsxs(Box, {
|
|
3370
|
+
flexDirection: "column",
|
|
3371
|
+
flexGrow: 1,
|
|
3372
|
+
children: [
|
|
3373
|
+
outroData.kind === "success" && /* @__PURE__ */ jsxs(Box, {
|
|
3374
|
+
flexDirection: "column",
|
|
3375
|
+
children: [
|
|
3376
|
+
/* @__PURE__ */ jsx(FinalScorePanel, { checks }),
|
|
3377
|
+
/* @__PURE__ */ jsx(Box, {
|
|
3378
|
+
marginTop: 1,
|
|
3379
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
3380
|
+
bold: true,
|
|
3381
|
+
color: "green",
|
|
3382
|
+
children: [
|
|
3383
|
+
"✔",
|
|
3384
|
+
" ",
|
|
3385
|
+
outroData.message || "AUDIT-3000 complete!"
|
|
3386
|
+
]
|
|
3387
|
+
})
|
|
3388
|
+
}),
|
|
3389
|
+
outroData.reportFile && /* @__PURE__ */ jsxs(Box, {
|
|
3390
|
+
flexDirection: "column",
|
|
3391
|
+
marginTop: 1,
|
|
3392
|
+
children: [
|
|
3393
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3394
|
+
bold: true,
|
|
3395
|
+
color: "cyan",
|
|
3396
|
+
children: "High-score reel saved to:"
|
|
3397
|
+
}),
|
|
3398
|
+
/* @__PURE__ */ jsx(Text, { children: join(store.session.installDir, outroData.reportFile) }),
|
|
3399
|
+
/* @__PURE__ */ jsx(Text, {
|
|
3400
|
+
dimColor: true,
|
|
3401
|
+
children: "A markdown file in your project folder — open it in any editor to read the full audit."
|
|
3402
|
+
})
|
|
3403
|
+
]
|
|
3404
|
+
}),
|
|
3405
|
+
/* @__PURE__ */ jsx(AuditChecksOutroSection, {
|
|
3406
|
+
checks,
|
|
3407
|
+
installDir: store.session.installDir
|
|
3408
|
+
}),
|
|
3409
|
+
outroData.docsUrl && /* @__PURE__ */ jsx(Box, {
|
|
3410
|
+
marginTop: 1,
|
|
3411
|
+
children: /* @__PURE__ */ jsxs(Text, { children: ["Learn more: ", /* @__PURE__ */ jsx(Text, {
|
|
3412
|
+
color: "cyan",
|
|
3413
|
+
children: outroData.docsUrl
|
|
3414
|
+
})] })
|
|
3415
|
+
})
|
|
3416
|
+
]
|
|
3417
|
+
}),
|
|
3418
|
+
outroData.kind === "error" && /* @__PURE__ */ jsxs(Box, {
|
|
3419
|
+
flexDirection: "column",
|
|
3420
|
+
children: [/* @__PURE__ */ jsxs(Text, {
|
|
3421
|
+
color: "red",
|
|
3422
|
+
bold: true,
|
|
3423
|
+
children: [
|
|
3424
|
+
"✘",
|
|
3425
|
+
" ",
|
|
3426
|
+
outroData.message || "An error occurred"
|
|
3427
|
+
]
|
|
3428
|
+
}), outroData.body && /* @__PURE__ */ jsx(Box, {
|
|
3429
|
+
marginTop: 1,
|
|
3430
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
3431
|
+
dimColor: true,
|
|
3432
|
+
children: outroData.body
|
|
3433
|
+
})
|
|
3434
|
+
})]
|
|
3435
|
+
}),
|
|
3436
|
+
outroData.kind === "cancel" && /* @__PURE__ */ jsxs(Text, {
|
|
3437
|
+
color: "yellow",
|
|
3438
|
+
children: [
|
|
3439
|
+
"■",
|
|
3440
|
+
" ",
|
|
3441
|
+
outroData.message || "Cancelled"
|
|
3442
|
+
]
|
|
3443
|
+
}),
|
|
3444
|
+
/* @__PURE__ */ jsx(Box, {
|
|
3445
|
+
marginTop: 1,
|
|
3446
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
3447
|
+
color: Colors.muted,
|
|
3448
|
+
children: "Press any key to continue"
|
|
3449
|
+
})
|
|
3450
|
+
})
|
|
3451
|
+
]
|
|
3452
|
+
});
|
|
3453
|
+
};
|
|
3454
|
+
//#endregion
|
|
2275
3455
|
//#region src/ui/tui/screens/SetupScreen.tsx
|
|
2276
3456
|
/**
|
|
2277
3457
|
* SetupScreen — Generic framework disambiguation.
|
|
@@ -2922,6 +4102,9 @@ function createScreens(store, services) {
|
|
|
2922
4102
|
["audit-intro"]: /* @__PURE__ */ jsx(AuditIntroScreen, { store }),
|
|
2923
4103
|
["audit-run"]: /* @__PURE__ */ jsx(AuditRunScreen, { store }),
|
|
2924
4104
|
["audit-outro"]: /* @__PURE__ */ jsx(AuditOutroScreen, { store }),
|
|
4105
|
+
["audit-3000-intro"]: /* @__PURE__ */ jsx(Audit3000IntroScreen, { store }),
|
|
4106
|
+
["audit-3000-run"]: /* @__PURE__ */ jsx(Audit3000RunScreen, { store }),
|
|
4107
|
+
["audit-3000-outro"]: /* @__PURE__ */ jsx(Audit3000OutroScreen, { store }),
|
|
2925
4108
|
["health-check"]: /* @__PURE__ */ jsx(HealthCheckScreen, { store }),
|
|
2926
4109
|
["doctor-intro"]: /* @__PURE__ */ jsx(DoctorIntroScreen, { store }),
|
|
2927
4110
|
["doctor-report"]: /* @__PURE__ */ jsx(DoctorReportScreen, { store }),
|
|
@@ -3009,4 +4192,4 @@ function startTUI(version, flow = "posthog-integration") {
|
|
|
3009
4192
|
//#endregion
|
|
3010
4193
|
export { startTUI };
|
|
3011
4194
|
|
|
3012
|
-
//# sourceMappingURL=start-tui-
|
|
4195
|
+
//# sourceMappingURL=start-tui-B_zwutLe.js.map
|