@codeyam/codeyam-cli 0.1.0-staging.7c30edc → 0.1.0-staging.80e493d
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/analyzer-template/.build-info.json +7 -7
- package/analyzer-template/log.txt +3 -3
- package/analyzer-template/package.json +13 -13
- package/analyzer-template/packages/ai/index.ts +1 -0
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +14 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +232 -5
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +29 -18
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/stripNullableMarkers.ts +35 -0
- package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +15 -6
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +96 -0
- package/analyzer-template/packages/analyze/src/lib/asts/nodes/getNodeType.ts +1 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +18 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +50 -25
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +153 -76
- package/analyzer-template/packages/aws/package.json +10 -10
- package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +98 -3
- package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
- package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +121 -3
- package/analyzer-template/project/constructMockCode.ts +34 -7
- package/analyzer-template/project/orchestrateCapture.ts +4 -1
- package/analyzer-template/project/writeScenarioComponents.ts +76 -12
- package/background/src/lib/virtualized/project/constructMockCode.js +30 -7
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture.js +4 -1
- package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +56 -7
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/codeyam-cli/scripts/apply-setup.js +1 -1
- package/codeyam-cli/src/cli.js +31 -20
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/commands/analyze.js +2 -2
- package/codeyam-cli/src/commands/analyze.js.map +1 -1
- package/codeyam-cli/src/commands/default.js +6 -1
- package/codeyam-cli/src/commands/default.js.map +1 -1
- package/codeyam-cli/src/commands/memory.js +64 -74
- package/codeyam-cli/src/commands/memory.js.map +1 -1
- package/codeyam-cli/src/commands/setup-simulations.js +1 -1
- package/codeyam-cli/src/commands/verify.js +12 -2
- package/codeyam-cli/src/commands/verify.js.map +1 -1
- package/codeyam-cli/src/utils/__tests__/npmVersionCheck.test.js +185 -0
- package/codeyam-cli/src/utils/__tests__/npmVersionCheck.test.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +11 -11
- package/codeyam-cli/src/utils/backgroundServer.js +90 -23
- package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/utils/generateReport.js +2 -2
- package/codeyam-cli/src/utils/install-skills.js +13 -13
- package/codeyam-cli/src/utils/labsAutoCheck.js +0 -29
- package/codeyam-cli/src/utils/labsAutoCheck.js.map +1 -1
- package/codeyam-cli/src/utils/npmVersionCheck.js +76 -0
- package/codeyam-cli/src/utils/npmVersionCheck.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +1 -1
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -1
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +0 -1
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -1
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +2 -4
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -1
- package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +2 -1
- package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -1
- package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +1 -1
- package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -1
- package/codeyam-cli/src/utils/rules/__tests__/parser.test.js +83 -0
- package/codeyam-cli/src/utils/rules/__tests__/parser.test.js.map +1 -0
- package/codeyam-cli/src/utils/rules/__tests__/pathMatcher.test.js +118 -0
- package/codeyam-cli/src/utils/rules/__tests__/pathMatcher.test.js.map +1 -0
- package/codeyam-cli/src/utils/rules/__tests__/sourceFiles.test.js +83 -0
- package/codeyam-cli/src/utils/rules/__tests__/sourceFiles.test.js.map +1 -0
- package/codeyam-cli/src/utils/rules/index.js +1 -0
- package/codeyam-cli/src/utils/rules/index.js.map +1 -1
- package/codeyam-cli/src/utils/rules/parser.js +14 -4
- package/codeyam-cli/src/utils/rules/parser.js.map +1 -1
- package/codeyam-cli/src/utils/rules/pathMatcher.js +34 -3
- package/codeyam-cli/src/utils/rules/pathMatcher.js.map +1 -1
- package/codeyam-cli/src/utils/rules/sourceFiles.js +47 -0
- package/codeyam-cli/src/utils/rules/sourceFiles.js.map +1 -0
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +7 -7
- package/codeyam-cli/src/utils/simulationGateMiddleware.js +138 -0
- package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -0
- package/codeyam-cli/src/utils/syncMocksMiddleware.js +5 -24
- package/codeyam-cli/src/utils/syncMocksMiddleware.js.map +1 -1
- package/codeyam-cli/src/utils/versionInfo.js +46 -0
- package/codeyam-cli/src/utils/versionInfo.js.map +1 -1
- package/codeyam-cli/src/webserver/__tests__/dependency-smoke.test.js +66 -0
- package/codeyam-cli/src/webserver/__tests__/dependency-smoke.test.js.map +1 -0
- package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
- package/codeyam-cli/src/webserver/backgroundServer.js +26 -7
- package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/webserver/bootstrap.js +11 -0
- package/codeyam-cli/src/webserver/bootstrap.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-CA3JxPb7.js → CopyButton-jNYXRRNI.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-B86KKU7e.js → EntityItem-bwuHPyTa.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-B5ctlSYt.js → EntityTypeBadge-CvzqMxcu.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-BqY8gDAW.js → EntityTypeIcon-BH0XDim7.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-ClaLpuOo.js → InlineSpinner-EhOseatT.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-BDhPilK7.js → InteractivePreview-yjIHlOGa.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-VeqEBv9v.js → LibraryFunctionPreview-Cq5o8jL4.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-Bs7Nn1Jr.js → LoadingDots-BvMu2i-g.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-Bm3PmcCz.js → LogViewer-kgBTLoJD.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-C6PKeMYR.js → ReportIssueModal-BzPgx-xO.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-Gq3Ocjo6.js → SafeScreenshot-CwZrv-Ok.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-BNLaXBHR.js → ScenarioViewer-BX2Ny2Qj.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-CiwXDxLh.js → TruncatedFilePath-CDpEprKa.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{_index-B3TDXxnk.js → _index-BRx8ZGZo.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BtBFH820.js → activity.(_tab)-4S4yPfFw.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DHKuQSmR.js +17 -0
- package/codeyam-cli/src/webserver/build/client/assets/{book-open-PttOB2SF.js → book-open-D4IPYH_y.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-TJp6ofnp.js → chevron-down-CG65viiV.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{chunk-JZWAC4HX-JE9ZIoBl.js → chunk-JZWAC4HX-DB3aFuEO.js} +9 -9
- package/codeyam-cli/src/webserver/build/client/assets/{circle-check-CXhHQYrI.js → circle-check-igfMr5DY.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{copy-6y9ALfGT.js → copy-Coc4o_8c.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-Ca9fAY46.js → createLucideIcon-D1zB-pYc.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-C5lqplTC.js → dev.empty-JTAjQ54M.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-n38keI1k.js → entity._sha._-B0h9AqE6.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js → entity._sha.scenarios._scenarioId.fullscreen-DjLxr2JB.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-DGgZjdFg.js → entity._sha_.create-scenario-CtYowLOt.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-38yPijoD.js → entity._sha_.edit._scenarioId-PePWg17F.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entry.client-BSHEfydn.js → entry.client-I-Wo99C_.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DCPhhSMo.js → fileTableUtils-9sMMAiWJ.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{files-0N0YJQv7.js → files-Co65J0s3.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{git-DXnyr8uP.js → git-BdHOxVfg.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-B4MPiL7S.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-ChN9-fAY.js → index-CUM5iXwc.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-CcsFv748.js → index-_417gcQW.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/labs-DAvt-sy-.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-CTqLEAGU.js → loader-circle-TzRHMVog.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-e24d6600.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/memory-bAp4y2hv.js +92 -0
- package/codeyam-cli/src/webserver/build/client/assets/{pause-D6vreykR.js → pause-hjzB7t2z.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-DoB3B10-.js +62 -0
- package/codeyam-cli/src/webserver/build/client/assets/{search-B8VUL8nl.js → search-DcAwD_Ln.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{settings-BejnUJ6R.js → settings-CclxrcPK.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{simulations-CPoAg7Zo.js → simulations-DVNJVQgD.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{terminal-BrCP7uQo.js → terminal-DbEAHMbA.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-BZz2NjYa.js → triangle-alert-CAD5b1o_.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-DNwUduNu.js → useCustomSizes-BqgrAzs3.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-COky1GVF.js → useLastLogLine-DAFqfEDH.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-CpZgwliL.js → useReportContext-DZlYx2c4.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-Bv9JFvUO.js → useToast-ihdMtlf6.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/{index-CFKHuovO.js → index-C_nP9_jr.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-BEaMCeTu.js +273 -0
- package/codeyam-cli/src/webserver/build/server/index.js +1 -1
- package/codeyam-cli/src/webserver/build-info.json +5 -5
- package/codeyam-cli/templates/{codeyam:debug.md → codeyam-debug.md} +1 -1
- package/codeyam-cli/templates/{codeyam:diagnose.md → codeyam-diagnose.md} +1 -1
- package/codeyam-cli/templates/{codeyam:memory.md → codeyam-memory.md} +7 -3
- package/codeyam-cli/templates/{codeyam:new-rule.md → codeyam-new-rule.md} +1 -1
- package/codeyam-cli/templates/{codeyam:setup.md → codeyam-setup.md} +1 -1
- package/codeyam-cli/templates/{codeyam:sim.md → codeyam-sim.md} +1 -1
- package/codeyam-cli/templates/{codeyam:test.md → codeyam-test.md} +1 -1
- package/codeyam-cli/templates/{codeyam:verify.md → codeyam-verify.md} +1 -1
- package/codeyam-cli/templates/rule-reflection-hook.py +1 -1
- package/codeyam-cli/templates/rules-instructions.md +1 -1
- package/package.json +12 -12
- package/packages/ai/index.js +1 -1
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/analyzeScope.js +14 -0
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +213 -3
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +24 -16
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
- package/packages/ai/src/lib/dataStructureChunking.js +9 -5
- package/packages/ai/src/lib/dataStructureChunking.js.map +1 -1
- package/packages/ai/src/lib/generateExecutionFlows.js +81 -0
- package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
- package/packages/analyze/src/lib/asts/nodes/getNodeType.js +1 -0
- package/packages/analyze/src/lib/asts/nodes/getNodeType.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +11 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +42 -13
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +123 -67
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/utils/src/lib/fs/rsyncCopy.js +98 -3
- package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-CN61MOMa.js +0 -11
- package/codeyam-cli/src/webserver/build/client/assets/api.labs-survey-l0sNRNKZ.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/globals-CuCsBc3b.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/labs-CB3MGcys.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-de6ccaf4.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/memory-DCA-kLYt.js +0 -81
- package/codeyam-cli/src/webserver/build/client/assets/root-F7e6dvys.js +0 -62
- package/codeyam-cli/src/webserver/build/server/assets/server-build-BQe9Dh4p.js +0 -260
|
@@ -1,4 +1,87 @@
|
|
|
1
|
-
import { spawn } from 'child_process';
|
|
1
|
+
import { execSync, spawn } from 'child_process';
|
|
2
|
+
import { existsSync, readdirSync, rmSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Try to use APFS copy-on-write clones on macOS for near-instant directory copies.
|
|
7
|
+
* Falls back to rsync on non-macOS or if the clone fails.
|
|
8
|
+
*
|
|
9
|
+
* Returns true if the clone succeeded (caller can skip rsync).
|
|
10
|
+
*/
|
|
11
|
+
function tryApfsClone({
|
|
12
|
+
sourcePath,
|
|
13
|
+
destinationPath,
|
|
14
|
+
excludes,
|
|
15
|
+
silent,
|
|
16
|
+
}: {
|
|
17
|
+
sourcePath: string;
|
|
18
|
+
destinationPath: string;
|
|
19
|
+
excludes: string[];
|
|
20
|
+
silent: boolean;
|
|
21
|
+
}): boolean {
|
|
22
|
+
if (process.platform !== 'darwin') return false;
|
|
23
|
+
|
|
24
|
+
// APFS clone requires the destination to not exist.
|
|
25
|
+
// If it exists and is empty, remove it so we can clone into it.
|
|
26
|
+
if (existsSync(destinationPath)) {
|
|
27
|
+
try {
|
|
28
|
+
const contents = readdirSync(destinationPath);
|
|
29
|
+
if (contents.length > 0) {
|
|
30
|
+
// Destination is non-empty — can't use clone, fall back to rsync
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
rmSync(destinationPath, { recursive: true });
|
|
34
|
+
} catch {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
// cp -c -R: APFS copy-on-write clone (faster than rsync, avoids data copy)
|
|
41
|
+
execSync(`cp -c -R "${sourcePath}" "${destinationPath}"`, {
|
|
42
|
+
stdio: 'pipe',
|
|
43
|
+
timeout: 300_000, // 5 min safety timeout
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Remove excluded items from the clone
|
|
47
|
+
for (const exclude of excludes) {
|
|
48
|
+
if (exclude.includes('*')) {
|
|
49
|
+
// Glob pattern — use shell expansion
|
|
50
|
+
try {
|
|
51
|
+
execSync(`rm -rf "${join(destinationPath, exclude)}"`, {
|
|
52
|
+
stdio: 'pipe',
|
|
53
|
+
shell: '/bin/sh',
|
|
54
|
+
});
|
|
55
|
+
} catch {
|
|
56
|
+
// Glob matched nothing — fine
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
const excludePath = join(destinationPath, exclude);
|
|
60
|
+
if (existsSync(excludePath)) {
|
|
61
|
+
rmSync(excludePath, { recursive: true, force: true });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!silent) {
|
|
67
|
+
console.log(
|
|
68
|
+
`Directory cloned (APFS CoW) from ${sourcePath} to ${destinationPath}`,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
} catch {
|
|
73
|
+
// Clone failed (cross-volume, non-APFS, etc.) — fall back to rsync
|
|
74
|
+
// Clean up any partial clone
|
|
75
|
+
if (existsSync(destinationPath)) {
|
|
76
|
+
try {
|
|
77
|
+
rmSync(destinationPath, { recursive: true });
|
|
78
|
+
} catch {
|
|
79
|
+
// Best effort cleanup
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
2
85
|
|
|
3
86
|
export default async function rsyncCopy({
|
|
4
87
|
sourcePath,
|
|
@@ -15,13 +98,38 @@ export default async function rsyncCopy({
|
|
|
15
98
|
silent?: boolean;
|
|
16
99
|
extraArgs?: string[];
|
|
17
100
|
}): Promise<void> {
|
|
101
|
+
const startTime = Date.now();
|
|
102
|
+
|
|
103
|
+
// On macOS, try APFS copy-on-write clone first (near-instant).
|
|
104
|
+
// Skip when extraArgs are provided since those are rsync-specific flags
|
|
105
|
+
// that the clone path can't honor.
|
|
106
|
+
if (!keepExisting && extraArgs.length === 0) {
|
|
107
|
+
const cloned = tryApfsClone({
|
|
108
|
+
sourcePath,
|
|
109
|
+
destinationPath,
|
|
110
|
+
excludes,
|
|
111
|
+
silent,
|
|
112
|
+
});
|
|
113
|
+
if (cloned) {
|
|
114
|
+
if (!silent) {
|
|
115
|
+
const duration = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
116
|
+
console.log(
|
|
117
|
+
`Directory synced from ${sourcePath} to ${destinationPath} [Time: ${duration}s]`,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Fall back to rsync
|
|
18
125
|
return new Promise((resolve, reject) => {
|
|
19
126
|
const source = sourcePath.endsWith('/') ? sourcePath : `${sourcePath}/`;
|
|
20
127
|
const dest = destinationPath.endsWith('/')
|
|
21
128
|
? destinationPath
|
|
22
129
|
: `${destinationPath}/`;
|
|
23
130
|
|
|
24
|
-
|
|
131
|
+
// -a includes --specials which tries to copy sockets/FIFOs and can fail
|
|
132
|
+
const rsyncArgs = ['-a', '--no-specials'];
|
|
25
133
|
|
|
26
134
|
if (!keepExisting) {
|
|
27
135
|
rsyncArgs.push('--delete', '--force');
|
|
@@ -37,7 +145,6 @@ export default async function rsyncCopy({
|
|
|
37
145
|
|
|
38
146
|
rsyncArgs.push(source, dest);
|
|
39
147
|
|
|
40
|
-
const startTime = Date.now();
|
|
41
148
|
const rsyncProcess = spawn('rsync', rsyncArgs);
|
|
42
149
|
|
|
43
150
|
rsyncProcess.on('exit', (code) => {
|
|
@@ -50,6 +157,17 @@ export default async function rsyncCopy({
|
|
|
50
157
|
}
|
|
51
158
|
resolve();
|
|
52
159
|
} else {
|
|
160
|
+
console.error(
|
|
161
|
+
`CodeYam Error: rsync failed with code: ${code}`,
|
|
162
|
+
JSON.stringify(
|
|
163
|
+
{
|
|
164
|
+
rsyncArgs,
|
|
165
|
+
},
|
|
166
|
+
null,
|
|
167
|
+
2,
|
|
168
|
+
),
|
|
169
|
+
);
|
|
170
|
+
|
|
53
171
|
reject(new Error(`rsync failed with exit code ${code}`));
|
|
54
172
|
}
|
|
55
173
|
});
|
|
@@ -342,7 +342,7 @@ export default function constructMockCode(
|
|
|
342
342
|
let foundEntityWithSignature = false;
|
|
343
343
|
let signatureSchema: DataStructure['signatureSchema'] | undefined;
|
|
344
344
|
|
|
345
|
-
for (const filePath in dependencySchemas) {
|
|
345
|
+
entitySearch: for (const filePath in dependencySchemas) {
|
|
346
346
|
for (const entityName in dependencySchemas[filePath]) {
|
|
347
347
|
// Match entity by base name (without generics/args)
|
|
348
348
|
const entityBaseName = entityName.split(/[<(]/)[0];
|
|
@@ -386,7 +386,7 @@ export default function constructMockCode(
|
|
|
386
386
|
// However, we still need to remove duplicate function calls that create invalid syntax
|
|
387
387
|
removeDuplicateFunctionCalls(relevantReturnValueSchema);
|
|
388
388
|
dataStructureValue = relevantReturnValueSchema?.[dataStructurePath];
|
|
389
|
-
break;
|
|
389
|
+
break entitySearch;
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
392
|
}
|
|
@@ -2288,6 +2288,23 @@ export default function constructMockCode(
|
|
|
2288
2288
|
}
|
|
2289
2289
|
}
|
|
2290
2290
|
|
|
2291
|
+
// Post-processing: When the root functionCallReturnValue is typed as "function" but the
|
|
2292
|
+
// return value also has nested properties (methods like .from(), .auth, etc.), it's actually
|
|
2293
|
+
// an object, not a function to be called. Clear returnsFunctionArgs to prevent double-wrapping
|
|
2294
|
+
// (adding an extra () => { return { ... } } wrapper and ["()"] data paths).
|
|
2295
|
+
// This handles cases like Supabase's createClient() which returns an object with methods.
|
|
2296
|
+
// Only applied to the root level - nested parts that are functions with methods (like
|
|
2297
|
+
// useSearchParams()[1] which is a setter function with .set() and .delete()) should keep
|
|
2298
|
+
// their returnsFunctionArgs since they genuinely ARE functions.
|
|
2299
|
+
if (
|
|
2300
|
+
returnValueParts.returnsFunctionArgs &&
|
|
2301
|
+
returnValueParts.returnsFunctionArgs.length === 0 &&
|
|
2302
|
+
returnValueParts.nested &&
|
|
2303
|
+
returnValueParts.nested.length > 0
|
|
2304
|
+
) {
|
|
2305
|
+
returnValueParts.returnsFunctionArgs = undefined;
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2291
2308
|
const contents = constructReturnValueString(returnValueParts);
|
|
2292
2309
|
|
|
2293
2310
|
if (mockNameParts.length > 1) {
|
|
@@ -2360,16 +2377,26 @@ export default function constructMockCode(
|
|
|
2360
2377
|
const nameAssignment = isErrorSubclass
|
|
2361
2378
|
? `this.name = '${baseMockName}';`
|
|
2362
2379
|
: '';
|
|
2363
|
-
// Use the
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2380
|
+
// Use the base class name for the class definition, not the call-signature-derived name.
|
|
2381
|
+
// When mockName is "StatsCalculator(supabase)", baseMockName is "StatsCalculator"
|
|
2382
|
+
// and derivedFunctionName would be "StatsCalculator_supabase" which is wrong.
|
|
2383
|
+
// Classes are instantiated with `new ClassName(args)` so the name must match the original.
|
|
2384
|
+
const className = baseMockName;
|
|
2385
|
+
|
|
2386
|
+
// Use the already-generated contents (which has proper function wrappers for methods)
|
|
2387
|
+
// instead of raw scenarios().data() which would create non-callable string-keyed properties.
|
|
2388
|
+
// For classes with methods like calculateStats(), the contents will have:
|
|
2389
|
+
// { calculateStats: (...args) => scenarios().data()?.["key"]?.["calculateStats(...)"], ... }
|
|
2390
|
+
// which makes methods callable on the instance.
|
|
2391
|
+
const classContents = enhancedContents.trim().startsWith('{')
|
|
2392
|
+
? enhancedContents
|
|
2393
|
+
: `scenarios().data()?.${quotePropertyKey(dataKey)} || {}`;
|
|
2367
2394
|
|
|
2368
2395
|
return `class ${className}${isErrorSubclass ? ' extends Error' : ''} {
|
|
2369
2396
|
constructor(message) {
|
|
2370
2397
|
${superCall}
|
|
2371
2398
|
${nameAssignment}
|
|
2372
|
-
Object.assign(this,
|
|
2399
|
+
Object.assign(this, ${classContents});
|
|
2373
2400
|
}
|
|
2374
2401
|
}`;
|
|
2375
2402
|
}
|
|
@@ -32,7 +32,10 @@ import type {
|
|
|
32
32
|
} from './orchestrateCapture/taskRunner';
|
|
33
33
|
import KyselyAnalysisLoader from './orchestrateCapture/KyselyAnalysisLoader';
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
// Temporarily set to 1 (effectively disabling batching) to work around reliability
|
|
36
|
+
// issues where multi-analysis batches cause cascading failures. Revisit once we
|
|
37
|
+
// reassess the SQS protocol and worker error handling.
|
|
38
|
+
const MAX_BATCH_SIZE = 1;
|
|
36
39
|
const POLLING_INTERVAL = 30 * 1000; // 30 seconds
|
|
37
40
|
const TASK_HEALTH_CHECK_INTERVAL = 60 * 1000; // 1 minute
|
|
38
41
|
const ANALYSIS_TIMEOUT = 20 * 60 * 1000;
|
|
@@ -2020,20 +2020,25 @@ export default async function writeScenarioComponents({
|
|
|
2020
2020
|
// that stubbing would break (e.g., Zod schemas with .superRefine())
|
|
2021
2021
|
const isDataEntity = entityType === 'data' || entityType === 'type';
|
|
2022
2022
|
|
|
2023
|
-
//
|
|
2024
|
-
//
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
importedExport.calls?.
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
)
|
|
2032
|
-
);
|
|
2023
|
+
// If calls data shows the entity is only accessed via properties/methods
|
|
2024
|
+
// (e.g., formValidator.validate(), schema.superRefine()) and never directly
|
|
2025
|
+
// invoked (e.g., getInitialProps()), it's used as an object and should be
|
|
2026
|
+
// preserved rather than replaced with a Proxy stub.
|
|
2027
|
+
const onlyPropertyAccessed =
|
|
2028
|
+
importedExport.calls?.length > 0 &&
|
|
2029
|
+
!importedExport.calls.some((call: string) => {
|
|
2030
|
+
const afterName = call.slice(importedExport.name.length);
|
|
2031
|
+
return afterName.startsWith('(') || afterName.startsWith('<');
|
|
2032
|
+
});
|
|
2033
2033
|
|
|
2034
|
-
// Callable entities can be safely stubbed
|
|
2034
|
+
// Callable entities can be safely stubbed. Entities that are only
|
|
2035
|
+
// property-accessed should be preserved (their methods need to work).
|
|
2036
|
+
// 'other' entities are unknown types — safer to preserve than stub.
|
|
2035
2037
|
const isCallable =
|
|
2036
|
-
!isDataEntity &&
|
|
2038
|
+
!isDataEntity &&
|
|
2039
|
+
!onlyPropertyAccessed &&
|
|
2040
|
+
entityType !== undefined &&
|
|
2041
|
+
entityType !== 'other';
|
|
2037
2042
|
|
|
2038
2043
|
// Determine what action to take
|
|
2039
2044
|
const shouldStripAndReplace = hasMock;
|
|
@@ -2733,6 +2738,20 @@ ${exportKeyword}const ${functionName} = new Proxy(() => scenarios().data()?.["${
|
|
|
2733
2738
|
debugLog(
|
|
2734
2739
|
`[REMAINING LOOP] import ${remainingImportIndex}/${remainingImportPaths.length}: ${importPath}`,
|
|
2735
2740
|
);
|
|
2741
|
+
|
|
2742
|
+
// Skip imports that point to generated CodeYam files (same skip logic as
|
|
2743
|
+
// rewriteRelativeModuleImports). Without this, MockData files from earlier
|
|
2744
|
+
// captures that get discovered by the TypeScript compiler would be treated as
|
|
2745
|
+
// regular imports, creating transitive copies with stale content.
|
|
2746
|
+
const scenarioFilePattern = /[a-f0-9]{64}_\w+_[A-Z]\w*$/;
|
|
2747
|
+
const mockDataPattern = /__codeyamMocks__\//;
|
|
2748
|
+
if (
|
|
2749
|
+
scenarioFilePattern.test(importPath) ||
|
|
2750
|
+
mockDataPattern.test(importPath)
|
|
2751
|
+
) {
|
|
2752
|
+
continue;
|
|
2753
|
+
}
|
|
2754
|
+
|
|
2736
2755
|
// Resolve the import path to a project file path
|
|
2737
2756
|
const resolvedFilePath = resolveImportPath(importPath, file.path, project);
|
|
2738
2757
|
|
|
@@ -3007,6 +3026,51 @@ ${exportKeyword}const ${functionName} = new Proxy(() => scenarios().data()?.["${
|
|
|
3007
3026
|
}
|
|
3008
3027
|
}
|
|
3009
3028
|
|
|
3029
|
+
// For route components (page.tsx, layout.tsx), the component IS the Next.js page.
|
|
3030
|
+
// There's no wrapper page to inject argumentsData as props (unlike non-route components
|
|
3031
|
+
// which get a scenarioComponent wrapper). We need to wrap the default export so that
|
|
3032
|
+
// the scenario's argumentsData is passed as props to the component.
|
|
3033
|
+
if (
|
|
3034
|
+
isFrameworkRoute(file, entity, framework, file === rootFile) &&
|
|
3035
|
+
rootAnalysis.metadata?.scenariosDataStructure?.arguments?.length > 0
|
|
3036
|
+
) {
|
|
3037
|
+
const positionalArguments =
|
|
3038
|
+
rootAnalysis.metadata.scenariosDataStructure.arguments;
|
|
3039
|
+
const hasNamedArgs =
|
|
3040
|
+
positionalArguments.length === 1 &&
|
|
3041
|
+
typeof positionalArguments[0] === 'object';
|
|
3042
|
+
|
|
3043
|
+
if (hasNamedArgs) {
|
|
3044
|
+
// Match: export default function Name(
|
|
3045
|
+
// Also: export default async function Name(
|
|
3046
|
+
const defaultExportMatch = fileContent.match(
|
|
3047
|
+
/export\s+default\s+(async\s+)?function\s+(\w+)\s*\(/,
|
|
3048
|
+
);
|
|
3049
|
+
|
|
3050
|
+
if (defaultExportMatch) {
|
|
3051
|
+
const funcName = defaultExportMatch[2];
|
|
3052
|
+
|
|
3053
|
+
// Remove "export default" from the original function declaration
|
|
3054
|
+
fileContent = fileContent.replace(
|
|
3055
|
+
/export\s+default\s+(async\s+)?function\s+(\w+)\s*\(/,
|
|
3056
|
+
'$1function $2(',
|
|
3057
|
+
);
|
|
3058
|
+
|
|
3059
|
+
// Ensure scenarios import is present
|
|
3060
|
+
const mockDataPath = `${relativeMocksDir}/MockData_${safeFileName(scenario.name)}`;
|
|
3061
|
+
if (fileContent.indexOf('import { scenarios } from') === -1) {
|
|
3062
|
+
fileContent = `import { scenarios } from "${mockDataPath}";\n\n${fileContent}`;
|
|
3063
|
+
}
|
|
3064
|
+
|
|
3065
|
+
// Add wrapper default export that injects argumentsData as props
|
|
3066
|
+
fileContent += `\n\nexport default function _CYRouteWrapper(props: any) {
|
|
3067
|
+
const _cyArgs = scenarios().data()?.['arguments']?.[0] ?? {};
|
|
3068
|
+
return <${funcName} {...props} {..._cyArgs} />;
|
|
3069
|
+
}\n`;
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
|
|
3010
3074
|
// Use the directive that was extracted at the beginning of processing
|
|
3011
3075
|
// This ensures it stays at the very top even after imports are prepended
|
|
3012
3076
|
// NOTE: We only preserve "use client" directives, NOT "use server" directives.
|
|
@@ -257,7 +257,7 @@ options) {
|
|
|
257
257
|
let dataStructureValue;
|
|
258
258
|
let foundEntityWithSignature = false;
|
|
259
259
|
let signatureSchema;
|
|
260
|
-
for (const filePath in dependencySchemas) {
|
|
260
|
+
entitySearch: for (const filePath in dependencySchemas) {
|
|
261
261
|
for (const entityName in dependencySchemas[filePath]) {
|
|
262
262
|
// Match entity by base name (without generics/args)
|
|
263
263
|
const entityBaseName = entityName.split(/[<(]/)[0];
|
|
@@ -289,7 +289,7 @@ options) {
|
|
|
289
289
|
// However, we still need to remove duplicate function calls that create invalid syntax
|
|
290
290
|
removeDuplicateFunctionCalls(relevantReturnValueSchema);
|
|
291
291
|
dataStructureValue = relevantReturnValueSchema?.[dataStructurePath];
|
|
292
|
-
break;
|
|
292
|
+
break entitySearch;
|
|
293
293
|
}
|
|
294
294
|
}
|
|
295
295
|
}
|
|
@@ -1917,6 +1917,20 @@ options) {
|
|
|
1917
1917
|
returnValueSection = relevantPart;
|
|
1918
1918
|
}
|
|
1919
1919
|
}
|
|
1920
|
+
// Post-processing: When the root functionCallReturnValue is typed as "function" but the
|
|
1921
|
+
// return value also has nested properties (methods like .from(), .auth, etc.), it's actually
|
|
1922
|
+
// an object, not a function to be called. Clear returnsFunctionArgs to prevent double-wrapping
|
|
1923
|
+
// (adding an extra () => { return { ... } } wrapper and ["()"] data paths).
|
|
1924
|
+
// This handles cases like Supabase's createClient() which returns an object with methods.
|
|
1925
|
+
// Only applied to the root level - nested parts that are functions with methods (like
|
|
1926
|
+
// useSearchParams()[1] which is a setter function with .set() and .delete()) should keep
|
|
1927
|
+
// their returnsFunctionArgs since they genuinely ARE functions.
|
|
1928
|
+
if (returnValueParts.returnsFunctionArgs &&
|
|
1929
|
+
returnValueParts.returnsFunctionArgs.length === 0 &&
|
|
1930
|
+
returnValueParts.nested &&
|
|
1931
|
+
returnValueParts.nested.length > 0) {
|
|
1932
|
+
returnValueParts.returnsFunctionArgs = undefined;
|
|
1933
|
+
}
|
|
1920
1934
|
const contents = constructReturnValueString(returnValueParts);
|
|
1921
1935
|
if (mockNameParts.length > 1) {
|
|
1922
1936
|
const originalLib = `${mockNameParts[0]}__cyOriginal`;
|
|
@@ -1978,15 +1992,24 @@ options) {
|
|
|
1978
1992
|
const nameAssignment = isErrorSubclass
|
|
1979
1993
|
? `this.name = '${baseMockName}';`
|
|
1980
1994
|
: '';
|
|
1981
|
-
// Use the
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1995
|
+
// Use the base class name for the class definition, not the call-signature-derived name.
|
|
1996
|
+
// When mockName is "StatsCalculator(supabase)", baseMockName is "StatsCalculator"
|
|
1997
|
+
// and derivedFunctionName would be "StatsCalculator_supabase" which is wrong.
|
|
1998
|
+
// Classes are instantiated with `new ClassName(args)` so the name must match the original.
|
|
1999
|
+
const className = baseMockName;
|
|
2000
|
+
// Use the already-generated contents (which has proper function wrappers for methods)
|
|
2001
|
+
// instead of raw scenarios().data() which would create non-callable string-keyed properties.
|
|
2002
|
+
// For classes with methods like calculateStats(), the contents will have:
|
|
2003
|
+
// { calculateStats: (...args) => scenarios().data()?.["key"]?.["calculateStats(...)"], ... }
|
|
2004
|
+
// which makes methods callable on the instance.
|
|
2005
|
+
const classContents = enhancedContents.trim().startsWith('{')
|
|
2006
|
+
? enhancedContents
|
|
2007
|
+
: `scenarios().data()?.${quotePropertyKey(dataKey)} || {}`;
|
|
1985
2008
|
return `class ${className}${isErrorSubclass ? ' extends Error' : ''} {
|
|
1986
2009
|
constructor(message) {
|
|
1987
2010
|
${superCall}
|
|
1988
2011
|
${nameAssignment}
|
|
1989
|
-
Object.assign(this,
|
|
2012
|
+
Object.assign(this, ${classContents});
|
|
1990
2013
|
}
|
|
1991
2014
|
}`;
|
|
1992
2015
|
}
|