@algolia/wizard 0.62.0 → 0.63.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/main.js +281 -108
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -1697,23 +1697,137 @@ function trackWorkflowError(ctx) {
|
|
|
1697
1697
|
|
|
1698
1698
|
// src/lib/events.ts
|
|
1699
1699
|
import "zod";
|
|
1700
|
-
|
|
1700
|
+
var analyticsAppId = void 0;
|
|
1701
|
+
var analyticsAgentRunId = void 0;
|
|
1702
|
+
function setAnalyticsContext(next) {
|
|
1703
|
+
analyticsAppId = next.appId;
|
|
1704
|
+
analyticsAgentRunId = next.agentRunId;
|
|
1705
|
+
}
|
|
1706
|
+
function wizardErrorType(actionId, step, error) {
|
|
1707
|
+
if (actionId === "project-scan" || step === "project scan") {
|
|
1708
|
+
return "Scan Codebase";
|
|
1709
|
+
}
|
|
1710
|
+
if (actionId === "ingestion" || step === "Push Data" || step === "ingest records") {
|
|
1711
|
+
return "Ingest Records";
|
|
1712
|
+
}
|
|
1713
|
+
if (actionId === "search" || step === "create search ui") {
|
|
1714
|
+
if (error && error.toLowerCase().includes("verification failed")) {
|
|
1715
|
+
return "Wire Component to UI";
|
|
1716
|
+
}
|
|
1717
|
+
return "Generate UI";
|
|
1718
|
+
}
|
|
1719
|
+
return void 0;
|
|
1720
|
+
}
|
|
1721
|
+
function commonEventProperties() {
|
|
1722
|
+
const properties = {};
|
|
1723
|
+
if (analyticsAppId) properties.app_id = analyticsAppId;
|
|
1724
|
+
if (analyticsAgentRunId) properties.agent_run_id = analyticsAgentRunId;
|
|
1725
|
+
return properties;
|
|
1726
|
+
}
|
|
1727
|
+
function postAnalytics(path, body, label) {
|
|
1701
1728
|
if (isTelemetryOptedOut()) return;
|
|
1702
1729
|
const token = getAuthToken();
|
|
1703
1730
|
if (!token) return;
|
|
1704
1731
|
const userId = useWizard.getState().user?.userId;
|
|
1705
1732
|
if (!userId) return;
|
|
1706
|
-
void proxyFetch(`${PROXY_BASE_URL}
|
|
1733
|
+
void proxyFetch(`${PROXY_BASE_URL}${path}`, {
|
|
1707
1734
|
method: "POST",
|
|
1708
1735
|
headers: {
|
|
1709
1736
|
"content-type": "application/json",
|
|
1710
1737
|
authorization: `Bearer ${token}`
|
|
1711
1738
|
},
|
|
1712
|
-
body: JSON.stringify(
|
|
1739
|
+
body: JSON.stringify(body)
|
|
1713
1740
|
}).catch((err) => {
|
|
1714
|
-
logger.warn({ err, event }, "failed to send analytics event");
|
|
1741
|
+
logger.warn({ err, event: label }, "failed to send analytics event");
|
|
1715
1742
|
});
|
|
1716
1743
|
}
|
|
1744
|
+
function track(event, payload) {
|
|
1745
|
+
postAnalytics(
|
|
1746
|
+
"/events",
|
|
1747
|
+
{
|
|
1748
|
+
userId: useWizard.getState().user?.userId,
|
|
1749
|
+
event,
|
|
1750
|
+
properties: { ...payload, ...commonEventProperties() }
|
|
1751
|
+
},
|
|
1752
|
+
event
|
|
1753
|
+
);
|
|
1754
|
+
}
|
|
1755
|
+
function identify(traits) {
|
|
1756
|
+
const userId = useWizard.getState().user?.userId;
|
|
1757
|
+
postAnalytics("/identify", { userId, traits }, "identify");
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
// package.json
|
|
1761
|
+
var package_default = {
|
|
1762
|
+
name: "@algolia/wizard",
|
|
1763
|
+
version: "0.63.0",
|
|
1764
|
+
description: "Magically implement Algolia functionality in your codebase",
|
|
1765
|
+
type: "module",
|
|
1766
|
+
engines: {
|
|
1767
|
+
node: ">=24"
|
|
1768
|
+
},
|
|
1769
|
+
bin: {
|
|
1770
|
+
wizard: "dist/main.js"
|
|
1771
|
+
},
|
|
1772
|
+
files: [
|
|
1773
|
+
"dist",
|
|
1774
|
+
"docs"
|
|
1775
|
+
],
|
|
1776
|
+
scripts: {
|
|
1777
|
+
"build:proxy": "node scripts/build.mjs proxy",
|
|
1778
|
+
build: "node scripts/build.mjs",
|
|
1779
|
+
"dev:proxy": "touch .env && NODE_OPTIONS=--use-system-ca tsx watch --env-file=.env src/proxy/index.ts",
|
|
1780
|
+
dev: "touch .env && tsx --env-file=.env ./src/main.tsx",
|
|
1781
|
+
"env:load": "pnpm exec -- varlock load",
|
|
1782
|
+
prepare: "husky",
|
|
1783
|
+
prepublishOnly: "pnpm build",
|
|
1784
|
+
reset: "tsx ./scripts/reset-state.ts",
|
|
1785
|
+
"test:fixtures": "touch .env && tsx --env-file=.env ./fixtures/run-fixtures.ts",
|
|
1786
|
+
"test:tools": "tsx ./tool-evals/toolEval.ts",
|
|
1787
|
+
"test:tools:improve": "tsx ./tool-evals/improveFromPlan.ts",
|
|
1788
|
+
test: "vitest",
|
|
1789
|
+
typecheck: "tsc --noEmit -p tsconfig.json"
|
|
1790
|
+
},
|
|
1791
|
+
keywords: [],
|
|
1792
|
+
author: "",
|
|
1793
|
+
license: "ISC",
|
|
1794
|
+
packageManager: "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
|
|
1795
|
+
devDependencies: {
|
|
1796
|
+
"@clack/prompts": "^1.6.0",
|
|
1797
|
+
"@types/ioredis-mock": "^8.2.7",
|
|
1798
|
+
"@types/node": "^25.9.1",
|
|
1799
|
+
"@types/react": "^19.2.16",
|
|
1800
|
+
esbuild: "^0.28.0",
|
|
1801
|
+
husky: "^9.1.7",
|
|
1802
|
+
"ink-testing-library": "^4.0.0",
|
|
1803
|
+
"ioredis-mock": "^8.13.1",
|
|
1804
|
+
"lint-staged": "^17.0.8",
|
|
1805
|
+
tsx: "^4.22.3",
|
|
1806
|
+
typescript: "^6.0.3",
|
|
1807
|
+
vitest: "^4.1.8"
|
|
1808
|
+
},
|
|
1809
|
+
dependencies: {
|
|
1810
|
+
"@ai-sdk/anthropic": "^3.0.81",
|
|
1811
|
+
"@ai-sdk/openai-compatible": "^2.0.47",
|
|
1812
|
+
"@hono/node-server": "^2.0.10",
|
|
1813
|
+
"@segment/analytics-node": "^3.1.0",
|
|
1814
|
+
ai: "^6.0.190",
|
|
1815
|
+
"cross-keychain": "^1.1.0",
|
|
1816
|
+
dotenv: "^17.4.2",
|
|
1817
|
+
hono: "^4.12.27",
|
|
1818
|
+
ink: "^7.0.5",
|
|
1819
|
+
"ink-picture": "^2.1.0",
|
|
1820
|
+
"ink-spinner": "^5.0.0",
|
|
1821
|
+
ioredis: "^5.11.1",
|
|
1822
|
+
nanoid: "^5.1.15",
|
|
1823
|
+
pino: "^10.3.1",
|
|
1824
|
+
react: "^19.2.7",
|
|
1825
|
+
"terminal-link": "^5.0.0",
|
|
1826
|
+
varlock: "^1.5.1",
|
|
1827
|
+
zod: "^4.4.3",
|
|
1828
|
+
zustand: "^5.0.14"
|
|
1829
|
+
}
|
|
1830
|
+
};
|
|
1717
1831
|
|
|
1718
1832
|
// src/core/orchestrator.ts
|
|
1719
1833
|
function defineStep(step) {
|
|
@@ -1766,9 +1880,37 @@ function initWorkflowState(workflow, now, appId) {
|
|
|
1766
1880
|
status: "pending"
|
|
1767
1881
|
})),
|
|
1768
1882
|
algoliaState: appId ? { appId } : {},
|
|
1769
|
-
userInputs: {}
|
|
1883
|
+
userInputs: {},
|
|
1884
|
+
agentRunId: crypto.randomUUID()
|
|
1885
|
+
};
|
|
1886
|
+
}
|
|
1887
|
+
function ensureAgentRunId(state) {
|
|
1888
|
+
if (!state.agentRunId) state.agentRunId = crypto.randomUUID();
|
|
1889
|
+
}
|
|
1890
|
+
function completeEventProperties(state, totalDurationMs, stepCount) {
|
|
1891
|
+
const indexName = state.steps.find((s) => s.id === "select-index")?.output?.selection;
|
|
1892
|
+
const framework = state.steps.find((s) => s.id === "confirm-framework")?.output?.frameworks?.[0]?.name;
|
|
1893
|
+
return {
|
|
1894
|
+
total_duration_ms: totalDurationMs,
|
|
1895
|
+
duration_ms: totalDurationMs,
|
|
1896
|
+
step_count: stepCount,
|
|
1897
|
+
index_name: indexName ?? "unknown",
|
|
1898
|
+
framework: framework ?? "unknown"
|
|
1770
1899
|
};
|
|
1771
1900
|
}
|
|
1901
|
+
function errorCodeFrom(err) {
|
|
1902
|
+
let current = err;
|
|
1903
|
+
for (let i = 0; i < 4 && current; i++) {
|
|
1904
|
+
if (current && typeof current === "object" && "statusCode" in current) {
|
|
1905
|
+
const code = current.statusCode;
|
|
1906
|
+
if (typeof code === "number" || typeof code === "string") {
|
|
1907
|
+
return String(code);
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
current = current instanceof Error ? current.cause : void 0;
|
|
1911
|
+
}
|
|
1912
|
+
return void 0;
|
|
1913
|
+
}
|
|
1772
1914
|
async function ensureConsent() {
|
|
1773
1915
|
const config = await loadConfig();
|
|
1774
1916
|
if (config.aiConsent) return;
|
|
@@ -1881,6 +2023,8 @@ async function runWorkflow(workflow, appId, options) {
|
|
|
1881
2023
|
try {
|
|
1882
2024
|
const state = await resolveWorkflowState(workflow, appId, options);
|
|
1883
2025
|
ensureExecutedStepCount(state);
|
|
2026
|
+
ensureAgentRunId(state);
|
|
2027
|
+
setAnalyticsContext({ appId, agentRunId: state.agentRunId });
|
|
1884
2028
|
store.startWorkflow(
|
|
1885
2029
|
{
|
|
1886
2030
|
id: workflow.id,
|
|
@@ -1891,6 +2035,11 @@ async function runWorkflow(workflow, appId, options) {
|
|
|
1891
2035
|
);
|
|
1892
2036
|
await ensureConsent();
|
|
1893
2037
|
trackWorkflowStart({ workflowId: workflow.id, appId });
|
|
2038
|
+
track("AI Wizard Started", {
|
|
2039
|
+
version: package_default.version,
|
|
2040
|
+
wizard_version: package_default.version,
|
|
2041
|
+
os: process.platform
|
|
2042
|
+
});
|
|
1894
2043
|
for (let i = state.currentStepIndex; i < workflow.steps.length; i++) {
|
|
1895
2044
|
await runStep(state, i, workflow.steps[i], appId);
|
|
1896
2045
|
}
|
|
@@ -1902,10 +2051,11 @@ async function runWorkflow(workflow, appId, options) {
|
|
|
1902
2051
|
total_duration: Math.round(totalDurationMs / 1e3),
|
|
1903
2052
|
total_steps: stepCount
|
|
1904
2053
|
});
|
|
1905
|
-
track(
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
2054
|
+
track(
|
|
2055
|
+
"AI Wizard Completed",
|
|
2056
|
+
completeEventProperties(state, totalDurationMs, stepCount)
|
|
2057
|
+
);
|
|
2058
|
+
identify({ is_Wizard_user: true });
|
|
1909
2059
|
await recordWorkflowRun(workflow.id, nowIso());
|
|
1910
2060
|
await clearWorkflowState(workflow.id);
|
|
1911
2061
|
store.setDone();
|
|
@@ -1946,10 +2096,15 @@ async function runWorkflow(workflow, appId, options) {
|
|
|
1946
2096
|
actionId: failedActionId,
|
|
1947
2097
|
cause: err
|
|
1948
2098
|
});
|
|
2099
|
+
const errorType = wizardErrorType(failedActionId, step, message);
|
|
2100
|
+
const errorCode2 = errorCodeFrom(err);
|
|
1949
2101
|
track("Error", {
|
|
1950
2102
|
step,
|
|
1951
2103
|
error: message,
|
|
1952
|
-
|
|
2104
|
+
error_message: message,
|
|
2105
|
+
product_area: "AI Wizard",
|
|
2106
|
+
...errorType ? { error_type: errorType } : {},
|
|
2107
|
+
...errorCode2 ? { error_code: errorCode2 } : {}
|
|
1953
2108
|
});
|
|
1954
2109
|
store.setError(message);
|
|
1955
2110
|
}
|
|
@@ -3529,7 +3684,7 @@ function generateRecordTool(ctx, createModel = defaultCreateModel2) {
|
|
|
3529
3684
|
try {
|
|
3530
3685
|
const anthropic = createModel();
|
|
3531
3686
|
const value = z17.union([z17.string(), z17.number(), z17.boolean(), z17.null()]);
|
|
3532
|
-
const
|
|
3687
|
+
const recordSchema2 = z17.object(
|
|
3533
3688
|
Object.fromEntries(attributes.map((attr) => [attr, value]))
|
|
3534
3689
|
);
|
|
3535
3690
|
const generateBatch = async (batchCount) => {
|
|
@@ -3540,7 +3695,7 @@ function generateRecordTool(ctx, createModel = defaultCreateModel2) {
|
|
|
3540
3695
|
model: anthropic(RECORD_MODEL),
|
|
3541
3696
|
output: Output2.object({
|
|
3542
3697
|
schema: z17.object({
|
|
3543
|
-
records: z17.array(
|
|
3698
|
+
records: z17.array(recordSchema2).length(batchCount)
|
|
3544
3699
|
})
|
|
3545
3700
|
}),
|
|
3546
3701
|
prompt: [
|
|
@@ -3975,78 +4130,6 @@ async function runAnalysis(mode, extraInstructions = []) {
|
|
|
3975
4130
|
return Object.assign({}, ...results);
|
|
3976
4131
|
}
|
|
3977
4132
|
|
|
3978
|
-
// package.json
|
|
3979
|
-
var package_default = {
|
|
3980
|
-
name: "@algolia/wizard",
|
|
3981
|
-
version: "0.62.0",
|
|
3982
|
-
description: "Magically implement Algolia functionality in your codebase",
|
|
3983
|
-
type: "module",
|
|
3984
|
-
engines: {
|
|
3985
|
-
node: ">=24"
|
|
3986
|
-
},
|
|
3987
|
-
bin: {
|
|
3988
|
-
wizard: "dist/main.js"
|
|
3989
|
-
},
|
|
3990
|
-
files: [
|
|
3991
|
-
"dist",
|
|
3992
|
-
"docs"
|
|
3993
|
-
],
|
|
3994
|
-
scripts: {
|
|
3995
|
-
"build:proxy": "node scripts/build.mjs proxy",
|
|
3996
|
-
build: "node scripts/build.mjs",
|
|
3997
|
-
"dev:proxy": "touch .env && NODE_OPTIONS=--use-system-ca tsx watch --env-file=.env src/proxy/index.ts",
|
|
3998
|
-
dev: "touch .env && tsx --env-file=.env ./src/main.tsx",
|
|
3999
|
-
"env:load": "pnpm exec -- varlock load",
|
|
4000
|
-
prepare: "husky",
|
|
4001
|
-
prepublishOnly: "pnpm build",
|
|
4002
|
-
reset: "tsx ./scripts/reset-state.ts",
|
|
4003
|
-
"test:fixtures": "touch .env && tsx --env-file=.env ./fixtures/run-fixtures.ts",
|
|
4004
|
-
"test:tools": "tsx ./tool-evals/toolEval.ts",
|
|
4005
|
-
"test:tools:improve": "tsx ./tool-evals/improveFromPlan.ts",
|
|
4006
|
-
test: "vitest",
|
|
4007
|
-
typecheck: "tsc --noEmit -p tsconfig.json"
|
|
4008
|
-
},
|
|
4009
|
-
keywords: [],
|
|
4010
|
-
author: "",
|
|
4011
|
-
license: "ISC",
|
|
4012
|
-
packageManager: "pnpm@11.9.0+sha512.bd682d5d03fe525ef7c9fd6780c6884d1e756ac4c9c9fe00c538782824310dcf90e3ddc4f53835f06dfaebd5085e41855e0bcbb3b60de2ac5bbab89e5036f03b",
|
|
4013
|
-
devDependencies: {
|
|
4014
|
-
"@clack/prompts": "^1.6.0",
|
|
4015
|
-
"@types/ioredis-mock": "^8.2.7",
|
|
4016
|
-
"@types/node": "^25.9.1",
|
|
4017
|
-
"@types/react": "^19.2.16",
|
|
4018
|
-
esbuild: "^0.28.0",
|
|
4019
|
-
husky: "^9.1.7",
|
|
4020
|
-
"ink-testing-library": "^4.0.0",
|
|
4021
|
-
"ioredis-mock": "^8.13.1",
|
|
4022
|
-
"lint-staged": "^17.0.8",
|
|
4023
|
-
tsx: "^4.22.3",
|
|
4024
|
-
typescript: "^6.0.3",
|
|
4025
|
-
vitest: "^4.1.8"
|
|
4026
|
-
},
|
|
4027
|
-
dependencies: {
|
|
4028
|
-
"@ai-sdk/anthropic": "^3.0.81",
|
|
4029
|
-
"@ai-sdk/openai-compatible": "^2.0.47",
|
|
4030
|
-
"@hono/node-server": "^2.0.10",
|
|
4031
|
-
"@segment/analytics-node": "^3.1.0",
|
|
4032
|
-
ai: "^6.0.190",
|
|
4033
|
-
"cross-keychain": "^1.1.0",
|
|
4034
|
-
dotenv: "^17.4.2",
|
|
4035
|
-
hono: "^4.12.27",
|
|
4036
|
-
ink: "^7.0.5",
|
|
4037
|
-
"ink-picture": "^2.1.0",
|
|
4038
|
-
"ink-spinner": "^5.0.0",
|
|
4039
|
-
ioredis: "^5.11.1",
|
|
4040
|
-
nanoid: "^5.1.15",
|
|
4041
|
-
pino: "^10.3.1",
|
|
4042
|
-
react: "^19.2.7",
|
|
4043
|
-
"terminal-link": "^5.0.0",
|
|
4044
|
-
varlock: "^1.5.1",
|
|
4045
|
-
zod: "^4.4.3",
|
|
4046
|
-
zustand: "^5.0.14"
|
|
4047
|
-
}
|
|
4048
|
-
};
|
|
4049
|
-
|
|
4050
4133
|
// src/actions/projectScan.ts
|
|
4051
4134
|
import "zod";
|
|
4052
4135
|
var projectScanSchema = detectLanguageSchema.extend({
|
|
@@ -4055,16 +4138,19 @@ var projectScanSchema = detectLanguageSchema.extend({
|
|
|
4055
4138
|
verification: analyzeCodebaseSchema.shape.verification
|
|
4056
4139
|
});
|
|
4057
4140
|
async function projectScan(ctx) {
|
|
4141
|
+
const startedAt = Date.now();
|
|
4058
4142
|
const [detected, analyses] = await Promise.all([
|
|
4059
4143
|
detectLanguage(),
|
|
4060
4144
|
runAnalysis()
|
|
4061
4145
|
]);
|
|
4062
|
-
|
|
4063
|
-
wizard_version: package_default.version,
|
|
4064
|
-
os: process.platform
|
|
4065
|
-
});
|
|
4146
|
+
const entities = toEntitySummary(analyses.ingestionAnalysis ?? []);
|
|
4066
4147
|
track("AI Wizard Scan Completed", {
|
|
4067
|
-
|
|
4148
|
+
languages: detected.languages,
|
|
4149
|
+
frameworks: detected.frameworks,
|
|
4150
|
+
data_models_found: entities.map((entity) => entity.name),
|
|
4151
|
+
back_end_language_detected: detected.languages[0]?.name ?? null,
|
|
4152
|
+
front_end_framework_detected: detected.frameworks[0]?.name ?? null,
|
|
4153
|
+
duration_ms: Date.now() - startedAt
|
|
4068
4154
|
});
|
|
4069
4155
|
for (const [key, value] of Object.entries(analyses)) {
|
|
4070
4156
|
ctx.setUserInput(key, value);
|
|
@@ -4162,7 +4248,7 @@ var isSameFramework = (a, b) => {
|
|
|
4162
4248
|
};
|
|
4163
4249
|
function confirmed(name, version) {
|
|
4164
4250
|
const frameworks = [{ name, version: version ?? "unknown" }];
|
|
4165
|
-
track("AI Wizard Frontend Framework Confirmed", { frameworks });
|
|
4251
|
+
track("AI Wizard Frontend Framework Confirmed", { frameworks, framework: name });
|
|
4166
4252
|
return { frameworks };
|
|
4167
4253
|
}
|
|
4168
4254
|
async function askOtherFramework(ctx) {
|
|
@@ -4266,6 +4352,11 @@ var confirmEntitiesSchema = z26.object({
|
|
|
4266
4352
|
confirmedEntities: confirmedEntitiesFieldSchema
|
|
4267
4353
|
});
|
|
4268
4354
|
var SUGGEST_ENTITY = "Suggest a different entity\u2026";
|
|
4355
|
+
function usedDetectedBackend(detected, confirmed2) {
|
|
4356
|
+
if (!detected?.length || !confirmed2?.length) return false;
|
|
4357
|
+
const detectedNames = new Set(detected.map((entry) => entry.name.toLowerCase()));
|
|
4358
|
+
return confirmed2.every((entry) => detectedNames.has(entry.name.toLowerCase()));
|
|
4359
|
+
}
|
|
4269
4360
|
async function askEntityName(ctx, opts) {
|
|
4270
4361
|
const blankHint = opts?.blankHint ?? "cancel";
|
|
4271
4362
|
const declared = await promptUser(ctx, {
|
|
@@ -4372,8 +4463,14 @@ async function confirmEntities(ctx) {
|
|
|
4372
4463
|
throw new Error("User cancelled entity selection \u2014 analysis halted.");
|
|
4373
4464
|
}
|
|
4374
4465
|
ctx.setUserInput("confirmedEntities", confirmed2);
|
|
4375
|
-
|
|
4376
|
-
|
|
4466
|
+
const languages = ctx.getStepOutput(
|
|
4467
|
+
"confirm-language"
|
|
4468
|
+
)?.languages;
|
|
4469
|
+
const summary = toEntitySummary(confirmed2);
|
|
4470
|
+
track("AI Wizard Data Model Confirmed", {
|
|
4471
|
+
data_model: summary[0]?.name ?? "unknown",
|
|
4472
|
+
attribute_count: summary[0]?.attributes.length ?? 0,
|
|
4473
|
+
used_detected_back_end: usedDetectedBackend(scan.languages, languages)
|
|
4377
4474
|
});
|
|
4378
4475
|
return { ingestionAnalysis: entities, confirmedEntities: confirmed2 };
|
|
4379
4476
|
}
|
|
@@ -4423,7 +4520,7 @@ ${formatCompletedSteps(ctx.completedSteps)}`,
|
|
|
4423
4520
|
|
|
4424
4521
|
// src/actions/implement.ts
|
|
4425
4522
|
import z28 from "zod";
|
|
4426
|
-
import { mkdir as mkdir5 } from "node:fs/promises";
|
|
4523
|
+
import { mkdir as mkdir5, readFile as readFile8 } from "node:fs/promises";
|
|
4427
4524
|
import { join as join10, relative as relative6 } from "node:path";
|
|
4428
4525
|
|
|
4429
4526
|
// src/lib/git.ts
|
|
@@ -4812,6 +4909,50 @@ function outputTail(output) {
|
|
|
4812
4909
|
if (!trimmed) return void 0;
|
|
4813
4910
|
return trimmed.length > INGEST_OUTPUT_TAIL_CHARS ? `\u2026${trimmed.slice(-INGEST_OUTPUT_TAIL_CHARS)}` : trimmed;
|
|
4814
4911
|
}
|
|
4912
|
+
function jsTypeName(value) {
|
|
4913
|
+
if (value === null) return "null";
|
|
4914
|
+
if (Array.isArray(value)) return "array";
|
|
4915
|
+
const type = typeof value;
|
|
4916
|
+
if (type === "string" || type === "number" || type === "boolean" || type === "object") {
|
|
4917
|
+
return type;
|
|
4918
|
+
}
|
|
4919
|
+
return "unknown";
|
|
4920
|
+
}
|
|
4921
|
+
async function firstRecordIn(filePath) {
|
|
4922
|
+
try {
|
|
4923
|
+
const parsed = JSON.parse(await readFile8(filePath, "utf8"));
|
|
4924
|
+
const first = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
4925
|
+
if (first && typeof first === "object" && !Array.isArray(first)) {
|
|
4926
|
+
return first;
|
|
4927
|
+
}
|
|
4928
|
+
} catch {
|
|
4929
|
+
return void 0;
|
|
4930
|
+
}
|
|
4931
|
+
return void 0;
|
|
4932
|
+
}
|
|
4933
|
+
async function ingestedRecordSample(repoRoot, entityName, uploadFilePath) {
|
|
4934
|
+
const candidates = [];
|
|
4935
|
+
if (entityName) {
|
|
4936
|
+
const slug = entityName.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
4937
|
+
candidates.push(join10(repoRoot, INGEST_DIR, "data", `${slug}.json`));
|
|
4938
|
+
}
|
|
4939
|
+
if (uploadFilePath?.toLowerCase().endsWith(".json")) {
|
|
4940
|
+
candidates.push(join10(repoRoot, uploadFilePath));
|
|
4941
|
+
}
|
|
4942
|
+
for (const candidate of candidates) {
|
|
4943
|
+
const sample = await firstRecordIn(candidate);
|
|
4944
|
+
if (sample) return sample;
|
|
4945
|
+
}
|
|
4946
|
+
return void 0;
|
|
4947
|
+
}
|
|
4948
|
+
function recordSchema(sample, attributes) {
|
|
4949
|
+
if (sample) {
|
|
4950
|
+
return Object.fromEntries(
|
|
4951
|
+
Object.entries(sample).map(([key, value]) => [key, jsTypeName(value)])
|
|
4952
|
+
);
|
|
4953
|
+
}
|
|
4954
|
+
return Object.fromEntries(attributes.map((key) => [key, "unknown"]));
|
|
4955
|
+
}
|
|
4815
4956
|
function ingestFailure(attempt, executions) {
|
|
4816
4957
|
if (!attempt) {
|
|
4817
4958
|
return {
|
|
@@ -5041,11 +5182,24 @@ async function implement(ctx, useCases = DEFAULT_IMPLEMENT_USE_CASES) {
|
|
|
5041
5182
|
if (ingestScriptRan) {
|
|
5042
5183
|
ingestOutcomeMessage = `\u2705 Ingestion succeeded${ingestRecordCount != null ? ` \u2014 ${ingestRecordCount} record(s) indexed.` : "."}`;
|
|
5043
5184
|
if (ingestRecordCount != null) {
|
|
5185
|
+
const data_model = confirmed2?.[0]?.name ?? "unknown";
|
|
5186
|
+
const sample = await ingestedRecordSample(
|
|
5187
|
+
repoRoot,
|
|
5188
|
+
confirmed2?.[0]?.name,
|
|
5189
|
+
uploadFilePath
|
|
5190
|
+
);
|
|
5044
5191
|
track("AI Wizard Ingest Successful", {
|
|
5045
|
-
|
|
5192
|
+
data_model,
|
|
5046
5193
|
record_count: ingestRecordCount,
|
|
5047
|
-
duration_ms: ingestDurationMs ?? 0
|
|
5194
|
+
duration_ms: ingestDurationMs ?? 0,
|
|
5195
|
+
index_name: targetIndex,
|
|
5196
|
+
record_schema: recordSchema(sample, confirmed2?.[0]?.attributes ?? [])
|
|
5048
5197
|
});
|
|
5198
|
+
} else {
|
|
5199
|
+
logger.warn(
|
|
5200
|
+
{ ingestCommand },
|
|
5201
|
+
"implement: ingestion ran but printed no record count; skipping Ingest Successful event"
|
|
5202
|
+
);
|
|
5049
5203
|
}
|
|
5050
5204
|
} else {
|
|
5051
5205
|
const { reason, detail } = ingestFailure(ingestAttempt, executions);
|
|
@@ -5069,7 +5223,10 @@ ${detail}` : ""}`
|
|
|
5069
5223
|
track("Error", {
|
|
5070
5224
|
step: "Push Data",
|
|
5071
5225
|
error: `ingestion did not complete: ${reason}`,
|
|
5072
|
-
|
|
5226
|
+
error_message: `ingestion did not complete: ${reason}`,
|
|
5227
|
+
error_type: "Ingest Records",
|
|
5228
|
+
product_area: "AI Wizard",
|
|
5229
|
+
...ingestAttempt?.exitCode != null ? { error_code: String(ingestAttempt.exitCode) } : {}
|
|
5073
5230
|
});
|
|
5074
5231
|
}
|
|
5075
5232
|
if (ingestScriptRan) {
|
|
@@ -5103,6 +5260,29 @@ ${detail}` : ""}`
|
|
|
5103
5260
|
let searchConfigFile;
|
|
5104
5261
|
if (useCases.includes("search")) {
|
|
5105
5262
|
let extraInstructions = [];
|
|
5263
|
+
const confirmedFrameworks = language.frameworks ?? [];
|
|
5264
|
+
const detectedFrameworks = scan.frameworks ?? [];
|
|
5265
|
+
const framework = confirmedFrameworks[0]?.name ?? "unknown";
|
|
5266
|
+
const used_detected_framework = confirmedFrameworks.some(
|
|
5267
|
+
(confirmedFw) => detectedFrameworks.some(
|
|
5268
|
+
(detectedFw) => isSameFramework(confirmedFw.name, detectedFw.name)
|
|
5269
|
+
)
|
|
5270
|
+
);
|
|
5271
|
+
const searchStartedAt = Date.now();
|
|
5272
|
+
const trackComponentGenerated = (mounted_successfully, attempts) => {
|
|
5273
|
+
const searchFilesChanged = [
|
|
5274
|
+
...new Set(useWizard.getState().writtenFiles)
|
|
5275
|
+
].map((file) => relative6(repoRoot, file));
|
|
5276
|
+
track("AI Wizard Frontend Component Generated", {
|
|
5277
|
+
file_paths: searchFilesChanged,
|
|
5278
|
+
framework,
|
|
5279
|
+
duration_ms: Date.now() - searchStartedAt,
|
|
5280
|
+
used_detected_framework,
|
|
5281
|
+
mounted_successfully,
|
|
5282
|
+
location_heuristic: searchLocation ?? "unknown",
|
|
5283
|
+
attempts
|
|
5284
|
+
});
|
|
5285
|
+
};
|
|
5106
5286
|
useWizard.getState().clearWrittenFiles();
|
|
5107
5287
|
for (let attempt = 1; attempt <= MAX_IMPLEMENT_VERIFICATION_ATTEMPTS; attempt++) {
|
|
5108
5288
|
if (attempt > 1) {
|
|
@@ -5127,19 +5307,12 @@ ${detail}` : ""}`
|
|
|
5127
5307
|
summaries.push(formatSummary("verification", verification.summary));
|
|
5128
5308
|
if (verification.sufficient) {
|
|
5129
5309
|
ctx.setUserInput("implementation", "success");
|
|
5130
|
-
|
|
5131
|
-
...new Set(useWizard.getState().writtenFiles)
|
|
5132
|
-
].map((file) => relative6(repoRoot, file));
|
|
5133
|
-
track("AI Wizard Frontend Component Generated", {
|
|
5134
|
-
filePaths: searchFilesChanged
|
|
5135
|
-
});
|
|
5136
|
-
track("AI Wizard Wired to UI", {
|
|
5137
|
-
location_heuristic: searchLocation ?? "unknown"
|
|
5138
|
-
});
|
|
5310
|
+
trackComponentGenerated(true, attempt);
|
|
5139
5311
|
break;
|
|
5140
5312
|
}
|
|
5141
5313
|
if (attempt === MAX_IMPLEMENT_VERIFICATION_ATTEMPTS) {
|
|
5142
5314
|
ctx.setUserInput("implementation", "fail");
|
|
5315
|
+
trackComponentGenerated(false, attempt);
|
|
5143
5316
|
throw new Error(
|
|
5144
5317
|
`Implementation verification failed after ${MAX_IMPLEMENT_VERIFICATION_ATTEMPTS} attempts: ${verification.additionalInstructions ?? verification.summary}`
|
|
5145
5318
|
);
|
|
@@ -6459,7 +6632,7 @@ function App() {
|
|
|
6459
6632
|
}
|
|
6460
6633
|
|
|
6461
6634
|
// src/lib/envAppId.ts
|
|
6462
|
-
import { readFile as
|
|
6635
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
6463
6636
|
import { join as join12 } from "node:path";
|
|
6464
6637
|
var ENV_FILES = [".env", ".env.local"];
|
|
6465
6638
|
var APP_ID_LINE = /^[ \t]*(?:export[ \t]+)?([A-Z0-9_]*ALGOLIA_APP(?:LICATION)?_ID)[ \t]*=[ \t]*(.*)$/gm;
|
|
@@ -6467,7 +6640,7 @@ async function findEnvApplicationId(root = process.cwd()) {
|
|
|
6467
6640
|
for (const file of ENV_FILES) {
|
|
6468
6641
|
let content;
|
|
6469
6642
|
try {
|
|
6470
|
-
content = await
|
|
6643
|
+
content = await readFile9(join12(root, file), "utf8");
|
|
6471
6644
|
} catch (err) {
|
|
6472
6645
|
if (err.code !== "ENOENT") {
|
|
6473
6646
|
logger.warn(
|
|
@@ -6820,7 +6993,7 @@ function delay(ms) {
|
|
|
6820
6993
|
// package.json with { type: 'json' }
|
|
6821
6994
|
var package_default2 = {
|
|
6822
6995
|
name: "@algolia/wizard",
|
|
6823
|
-
version: "0.
|
|
6996
|
+
version: "0.63.0",
|
|
6824
6997
|
description: "Magically implement Algolia functionality in your codebase",
|
|
6825
6998
|
type: "module",
|
|
6826
6999
|
engines: {
|