@codeyam/codeyam-cli 0.1.0-staging.6e699e5 → 0.1.0-staging.79ef713
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 +7 -7
- package/analyzer-template/packages/ai/index.ts +10 -2
- package/analyzer-template/packages/ai/package.json +2 -2
- package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +86 -18
- package/analyzer-template/packages/ai/src/lib/astScopes/astScopeAnalyzer.ts +67 -9
- package/analyzer-template/packages/ai/src/lib/astScopes/methodSemantics.ts +41 -17
- package/analyzer-template/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.ts +10 -17
- package/analyzer-template/packages/ai/src/lib/astScopes/processExpression.ts +308 -50
- package/analyzer-template/packages/ai/src/lib/astScopes/types.ts +15 -6
- package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +833 -243
- package/analyzer-template/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.ts +5 -1
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.ts +16 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.ts +6 -4
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.ts +54 -3
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.ts +60 -15
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.ts +70 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +80 -5
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.ts +179 -0
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.ts +40 -30
- package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.ts +393 -97
- package/analyzer-template/packages/ai/src/lib/generateEntityDataStructure.ts +58 -3
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarioData.ts +283 -1
- package/analyzer-template/packages/ai/src/lib/generateEntityScenarios.ts +9 -5
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +11 -3
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionalEffects.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromConditionals.ts +297 -7
- package/analyzer-template/packages/ai/src/lib/generateExecutionFlowsFromJsxUsages.ts +1 -1
- package/analyzer-template/packages/ai/src/lib/isolateScopes.ts +51 -3
- package/analyzer-template/packages/ai/src/lib/mergeStatements.ts +90 -96
- package/analyzer-template/packages/ai/src/lib/promptGenerators/gatherAttributesMap.ts +10 -7
- package/analyzer-template/packages/ai/src/lib/resolvePathToControllable.ts +25 -13
- package/analyzer-template/packages/ai/src/lib/worker/SerializableDataStructure.ts +4 -3
- package/analyzer-template/packages/ai/src/lib/worker/analyzeScopeWorker.ts +114 -2
- package/analyzer-template/packages/analyze/index.ts +2 -0
- package/analyzer-template/packages/analyze/src/lib/FileAnalyzer.ts +65 -59
- package/analyzer-template/packages/analyze/src/lib/ProjectAnalyzer.ts +113 -26
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.ts +19 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.ts +19 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getAllExports.ts +11 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.ts +8 -0
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.ts +49 -1
- package/analyzer-template/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +71 -9
- package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities.ts +19 -4
- package/analyzer-template/packages/analyze/src/lib/files/analyze/dependencyResolver.ts +6 -0
- package/analyzer-template/packages/analyze/src/lib/files/analyze/gatherEntityMap.ts +4 -2
- package/analyzer-template/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.ts +0 -3
- package/analyzer-template/packages/analyze/src/lib/files/analyzeRemixRoute.ts +4 -5
- package/analyzer-template/packages/analyze/src/lib/files/getImportedExports.ts +14 -12
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/TransformationTracer.ts +1315 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.ts +61 -13
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +37 -0
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateDataStructure.ts +229 -19
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.ts +117 -9
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +459 -39
- package/analyzer-template/packages/analyze/src/lib/files/scenarios/propagateArrayItemSchemas.ts +474 -0
- package/analyzer-template/packages/analyze/src/lib/files/setImportedExports.ts +2 -1
- package/analyzer-template/packages/analyze/src/lib/index.ts +1 -0
- package/analyzer-template/packages/analyze/src/lib/utils/getFileByPath.ts +19 -0
- package/analyzer-template/packages/aws/package.json +1 -1
- package/analyzer-template/packages/database/package.json +1 -1
- package/analyzer-template/packages/database/src/lib/kysely/db.ts +8 -1
- package/analyzer-template/packages/database/src/lib/kysely/tables/commitsTable.ts +6 -0
- package/analyzer-template/packages/database/src/lib/loadAnalyses.ts +58 -1
- package/analyzer-template/packages/database/src/lib/loadAnalysis.ts +13 -0
- package/analyzer-template/packages/database/src/lib/loadBranch.ts +16 -1
- package/analyzer-template/packages/database/src/lib/loadCommit.ts +11 -0
- package/analyzer-template/packages/database/src/lib/loadCommits.ts +28 -0
- package/analyzer-template/packages/database/src/lib/loadEntities.ts +26 -3
- package/analyzer-template/packages/database/src/lib/loadEntityBranches.ts +12 -0
- package/analyzer-template/packages/database/src/lib/updateCommitMetadata.ts +7 -14
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js +8 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/db.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts +1 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js +3 -0
- package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts +2 -0
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js +45 -2
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalyses.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js +8 -0
- package/analyzer-template/packages/github/dist/database/src/lib/loadAnalysis.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js +11 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadBranch.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js +7 -0
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommit.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts +3 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js +22 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadCommits.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts +3 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js +23 -4
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntities.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js +9 -0
- package/analyzer-template/packages/github/dist/database/src/lib/loadEntityBranches.js.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts +2 -2
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js +5 -4
- package/analyzer-template/packages/github/dist/database/src/lib/updateCommitMetadata.js.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts +2 -0
- package/analyzer-template/packages/github/dist/types/src/types/Commit.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts +3 -0
- package/analyzer-template/packages/github/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
- package/analyzer-template/packages/github/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
- package/analyzer-template/packages/github/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
- package/analyzer-template/packages/github/package.json +1 -1
- package/analyzer-template/packages/types/src/types/Commit.ts +2 -0
- package/analyzer-template/packages/types/src/types/ProjectMetadata.ts +1 -0
- package/analyzer-template/packages/types/src/types/ScenariosDataStructure.ts +6 -5
- package/analyzer-template/packages/types/src/types/ScopeAnalysis.ts +6 -1
- package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts +2 -0
- package/analyzer-template/packages/utils/dist/types/src/types/Commit.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts +3 -0
- package/analyzer-template/packages/utils/dist/types/src/types/ProjectMetadata.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts +5 -5
- package/analyzer-template/packages/utils/dist/types/src/types/ScenariosDataStructure.d.ts.map +1 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts +6 -1
- package/analyzer-template/packages/utils/dist/types/src/types/ScopeAnalysis.d.ts.map +1 -1
- package/analyzer-template/playwright/capture.ts +20 -8
- package/analyzer-template/playwright/captureStatic.ts +1 -1
- package/analyzer-template/project/analyzeBaselineCommit.ts +5 -0
- package/analyzer-template/project/analyzeRegularCommit.ts +5 -0
- package/analyzer-template/project/captureLibraryFunctionDirect.ts +29 -26
- package/analyzer-template/project/constructMockCode.ts +90 -10
- package/analyzer-template/project/createEntitiesAndSortFiles.ts +83 -0
- package/analyzer-template/project/loadReadyToBeCaptured.ts +65 -41
- package/analyzer-template/project/orchestrateCapture/AwsCaptureTaskRunner.ts +12 -4
- package/analyzer-template/project/orchestrateCapture/SequentialCaptureTaskRunner.ts +11 -6
- package/analyzer-template/project/orchestrateCapture/taskRunner.ts +4 -2
- package/analyzer-template/project/orchestrateCapture.ts +45 -6
- package/analyzer-template/project/start.ts +35 -11
- package/analyzer-template/project/writeMockDataTsx.ts +181 -8
- package/analyzer-template/project/writeScenarioComponents.ts +103 -12
- package/analyzer-template/project/writeSimpleRoot.ts +21 -11
- package/analyzer-template/scripts/comboWorkerLoop.cjs +98 -50
- package/background/src/lib/virtualized/project/analyzeBaselineCommit.js +5 -0
- package/background/src/lib/virtualized/project/analyzeBaselineCommit.js.map +1 -1
- package/background/src/lib/virtualized/project/analyzeRegularCommit.js +5 -0
- package/background/src/lib/virtualized/project/analyzeRegularCommit.js.map +1 -1
- package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js +3 -3
- package/background/src/lib/virtualized/project/captureLibraryFunctionDirect.js.map +1 -1
- package/background/src/lib/virtualized/project/constructMockCode.js +75 -4
- package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
- package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.js +73 -1
- package/background/src/lib/virtualized/project/createEntitiesAndSortFiles.js.map +1 -1
- package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js +19 -8
- package/background/src/lib/virtualized/project/loadReadyToBeCaptured.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.js +2 -2
- package/background/src/lib/virtualized/project/orchestrateCapture/AwsCaptureTaskRunner.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js +4 -4
- package/background/src/lib/virtualized/project/orchestrateCapture/SequentialCaptureTaskRunner.js.map +1 -1
- package/background/src/lib/virtualized/project/orchestrateCapture.js +38 -6
- package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
- package/background/src/lib/virtualized/project/start.js +32 -11
- package/background/src/lib/virtualized/project/start.js.map +1 -1
- package/background/src/lib/virtualized/project/writeMockDataTsx.js +162 -4
- package/background/src/lib/virtualized/project/writeMockDataTsx.js.map +1 -1
- package/background/src/lib/virtualized/project/writeScenarioComponents.js +85 -15
- package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
- package/background/src/lib/virtualized/project/writeSimpleRoot.js +21 -11
- package/background/src/lib/virtualized/project/writeSimpleRoot.js.map +1 -1
- package/codeyam-cli/scripts/apply-setup.js +180 -0
- package/codeyam-cli/scripts/apply-setup.js.map +1 -1
- package/codeyam-cli/src/cli.js +2 -0
- package/codeyam-cli/src/cli.js.map +1 -1
- package/codeyam-cli/src/commands/debug.js +7 -5
- package/codeyam-cli/src/commands/debug.js.map +1 -1
- package/codeyam-cli/src/commands/memory.js +264 -0
- package/codeyam-cli/src/commands/memory.js.map +1 -0
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +2 -2
- package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js.map +1 -1
- package/codeyam-cli/src/utils/analysisRunner.js +21 -2
- package/codeyam-cli/src/utils/analysisRunner.js.map +1 -1
- package/codeyam-cli/src/utils/backgroundServer.js +4 -0
- package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
- package/codeyam-cli/src/utils/install-skills.js +55 -10
- package/codeyam-cli/src/utils/install-skills.js.map +1 -1
- package/codeyam-cli/src/utils/queue/job.js +4 -0
- package/codeyam-cli/src/utils/queue/job.js.map +1 -1
- package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js +82 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/confusionDetector.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js +230 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/contextBuilder.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +67 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js +105 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/captureFixture.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js +34 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/loadCapturedFixture.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js +162 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/runClaude.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +75 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +285 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +115 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js +127 -0
- package/codeyam-cli/src/utils/ruleReflection/__tests__/transcriptParser.test.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js +50 -0
- package/codeyam-cli/src/utils/ruleReflection/confusionDetector.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +116 -0
- package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/index.js +5 -0
- package/codeyam-cli/src/utils/ruleReflection/index.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js +44 -0
- package/codeyam-cli/src/utils/ruleReflection/promptBuilder.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js +85 -0
- package/codeyam-cli/src/utils/ruleReflection/transcriptParser.js.map +1 -0
- package/codeyam-cli/src/utils/ruleReflection/types.js +5 -0
- package/codeyam-cli/src/utils/ruleReflection/types.js.map +1 -0
- package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js +293 -0
- package/codeyam-cli/src/utils/rules/__tests__/ruleState.test.js.map +1 -0
- package/codeyam-cli/src/utils/rules/index.js +6 -0
- package/codeyam-cli/src/utils/rules/index.js.map +1 -0
- package/codeyam-cli/src/utils/rules/parser.js +78 -0
- package/codeyam-cli/src/utils/rules/parser.js.map +1 -0
- package/codeyam-cli/src/utils/rules/pathMatcher.js +18 -0
- package/codeyam-cli/src/utils/rules/pathMatcher.js.map +1 -0
- package/codeyam-cli/src/utils/rules/ruleState.js +150 -0
- package/codeyam-cli/src/utils/rules/ruleState.js.map +1 -0
- package/codeyam-cli/src/utils/rules/staleness.js +137 -0
- package/codeyam-cli/src/utils/rules/staleness.js.map +1 -0
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +1 -1
- package/codeyam-cli/src/utils/setupClaudeCodeSettings.js.map +1 -1
- package/codeyam-cli/src/webserver/app/lib/database.js +7 -3
- package/codeyam-cli/src/webserver/app/lib/database.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/CopyButton-CA3JxPb7.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-B86KKU7e.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-DLqD3qNt.js → EntityTypeBadge-B5ctlSYt.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-Ba2JVPzP.js → EntityTypeIcon-BqY8gDAW.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-C8lyxW9k.js → InlineSpinner-ClaLpuOo.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-aht4aafF.js → InteractivePreview-BDhPilK7.js} +2 -2
- package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-CVtiBnY5.js → LibraryFunctionPreview-VeqEBv9v.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-B0GLXMsr.js → LoadingDots-Bs7Nn1Jr.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-xgeCVgSM.js → LogViewer-Bm3PmcCz.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-D4TZhLuw.js → ReportIssueModal-C6PKeMYR.js} +3 -13
- package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-DuDvi0jm.js → SafeScreenshot-Gq3Ocjo6.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-DEx02QDa.js → ScenarioViewer-BNLaXBHR.js} +3 -3
- package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-DyFZkK0l.js → TruncatedFilePath-CiwXDxLh.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{_index-BwqWJOgH.js → _index-B3TDXxnk.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-DoLIqZX2.js → activity.(_tab)-BtBFH820.js} +6 -16
- package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DfKzxuoe.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.memory-profile-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/api.save-fixture-l0sNRNKZ.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/book-open-PttOB2SF.js +6 -0
- package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-Cx24_aWc.js → chevron-down-TJp6ofnp.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{chunk-EPOLDU6W-CXRTFQ3F.js → chunk-JZWAC4HX-JE9ZIoBl.js} +12 -12
- package/codeyam-cli/src/webserver/build/client/assets/{circle-check-BOARzkeR.js → circle-check-CXhHQYrI.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/copy-6y9ALfGT.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-BdhJEx6B.js → createLucideIcon-Ca9fAY46.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-C5lqplTC.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-C2N4Op8e.js → entity._sha._-n38keI1k.js} +10 -10
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-DavjRmOY.js → entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-D1T4TGjf.js → entity._sha_.create-scenario-DGgZjdFg.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-CTBG2mmz.js → entity._sha_.edit._scenarioId-38yPijoD.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{entry.client-CS2cb_eZ.js → entry.client-BSHEfydn.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DMJ7zii9.js → fileTableUtils-DCPhhSMo.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-0N0YJQv7.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{git-B4RJRvYB.js → git-DXnyr8uP.js} +8 -8
- package/codeyam-cli/src/webserver/build/client/assets/globals-Bh6jH0cL.css +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{index-lzqtyFU8.js → index-CcsFv748.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{index-B1h680n5.js → index-ChN9-fAY.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/labs-CdVUfvji.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-B7B9V-bu.js → loader-circle-CTqLEAGU.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-87319d0f.js +1 -0
- package/codeyam-cli/src/webserver/build/client/assets/memory-CPIDnDEj.js +76 -0
- package/codeyam-cli/src/webserver/build/client/assets/pause-D6vreykR.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/root-D6oziHts.js +62 -0
- package/codeyam-cli/src/webserver/build/client/assets/{search-CxXUmBSd.js → search-B8VUL8nl.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{settings-CS5f3WzT.js → settings-eBI36Yv5.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{simulations-DwFIBT09.js → simulations-CPoAg7Zo.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/terminal-BrCP7uQo.js +11 -0
- package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-B6LgvRJg.js → triangle-alert-BZz2NjYa.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-C1v1PQzo.js → useCustomSizes-DNwUduNu.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-aSv48UbS.js → useLastLogLine-COky1GVF.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-DYxHZQuP.js → useReportContext-CpZgwliL.js} +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/{useToast-mBRpZPiu.js → useToast-Bv9JFvUO.js} +1 -1
- package/codeyam-cli/src/webserver/build/server/assets/index-9ox9LcrG.js +1 -0
- package/codeyam-cli/src/webserver/build/server/assets/server-build-Cq5Vqcob.js +260 -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-power-rules-hook.sh → codeyam-memory-hook.sh} +12 -13
- package/codeyam-cli/templates/codeyam:diagnose.md +178 -25
- package/codeyam-cli/templates/codeyam:memory.md +404 -0
- package/codeyam-cli/templates/codeyam:new-rule.md +2 -2
- package/codeyam-cli/templates/rule-notification-hook.py +56 -0
- package/codeyam-cli/templates/rule-reflection-hook.py +590 -0
- package/codeyam-cli/templates/rules-instructions.md +123 -0
- package/package.json +8 -6
- package/packages/ai/index.js +3 -2
- package/packages/ai/index.js.map +1 -1
- package/packages/ai/src/lib/analyzeScope.js +68 -13
- package/packages/ai/src/lib/analyzeScope.js.map +1 -1
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js +54 -8
- package/packages/ai/src/lib/astScopes/astScopeAnalyzer.js.map +1 -1
- package/packages/ai/src/lib/astScopes/methodSemantics.js +41 -17
- package/packages/ai/src/lib/astScopes/methodSemantics.js.map +1 -1
- package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js +10 -14
- package/packages/ai/src/lib/astScopes/patterns/forInStatementHandler.js.map +1 -1
- package/packages/ai/src/lib/astScopes/processExpression.js +239 -43
- package/packages/ai/src/lib/astScopes/processExpression.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +650 -166
- package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js +5 -1
- package/packages/ai/src/lib/dataStructure/equivalencyManagers/frameworks/JavascriptFrameworkManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js +13 -3
- package/packages/ai/src/lib/dataStructure/helpers/BatchSchemaProcessor.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js +6 -4
- package/packages/ai/src/lib/dataStructure/helpers/ScopeTreeManager.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js +52 -3
- package/packages/ai/src/lib/dataStructure/helpers/cleanKnownObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js +55 -11
- package/packages/ai/src/lib/dataStructure/helpers/cleanNonObjectFunctions.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js +63 -0
- package/packages/ai/src/lib/dataStructure/helpers/coerceObjectsToPrimitivesBySchema.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +73 -5
- package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js +173 -0
- package/packages/ai/src/lib/dataStructure/helpers/convertTypeAnnotationsToValues.js.map +1 -0
- package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js +37 -20
- package/packages/ai/src/lib/dataStructure/helpers/deduplicateFunctionSchemas.js.map +1 -1
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js +333 -86
- package/packages/ai/src/lib/dataStructure/helpers/fillInSchemaGapsAndUnknowns.js.map +1 -1
- package/packages/ai/src/lib/generateEntityDataStructure.js +46 -2
- package/packages/ai/src/lib/generateEntityDataStructure.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js +205 -1
- package/packages/ai/src/lib/generateEntityScenarioData.js.map +1 -1
- package/packages/ai/src/lib/generateEntityScenarios.js +7 -1
- package/packages/ai/src/lib/generateEntityScenarios.js.map +1 -1
- package/packages/ai/src/lib/generateExecutionFlows.js +10 -2
- package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js +209 -3
- package/packages/ai/src/lib/generateExecutionFlowsFromConditionals.js.map +1 -1
- package/packages/ai/src/lib/isolateScopes.js +39 -3
- package/packages/ai/src/lib/isolateScopes.js.map +1 -1
- package/packages/ai/src/lib/mergeStatements.js +70 -51
- package/packages/ai/src/lib/mergeStatements.js.map +1 -1
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js +10 -4
- package/packages/ai/src/lib/promptGenerators/gatherAttributesMap.js.map +1 -1
- package/packages/ai/src/lib/resolvePathToControllable.js +24 -14
- package/packages/ai/src/lib/resolvePathToControllable.js.map +1 -1
- package/packages/ai/src/lib/worker/SerializableDataStructure.js.map +1 -1
- package/packages/ai/src/lib/worker/analyzeScopeWorker.js +94 -1
- package/packages/ai/src/lib/worker/analyzeScopeWorker.js.map +1 -1
- package/packages/analyze/index.js +1 -0
- package/packages/analyze/index.js.map +1 -1
- package/packages/analyze/src/lib/FileAnalyzer.js +60 -36
- package/packages/analyze/src/lib/FileAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/ProjectAnalyzer.js +96 -26
- package/packages/analyze/src/lib/ProjectAnalyzer.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js +14 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllDeclaredEntityNodes.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js +14 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllEntityNodes.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js +6 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getAllExports.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js +6 -0
- package/packages/analyze/src/lib/asts/sourceFiles/getImportsAnalysis.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js +39 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getResolvedModule.js.map +1 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js +2 -1
- package/packages/analyze/src/lib/asts/sourceFiles/getSourceFilesForAllImports.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +54 -6
- package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js +17 -4
- package/packages/analyze/src/lib/files/analyze/analyzeEntities.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/dependencyResolver.js +5 -0
- package/packages/analyze/src/lib/files/analyze/dependencyResolver.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js +2 -1
- package/packages/analyze/src/lib/files/analyze/gatherEntityMap.js.map +1 -1
- package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js +0 -3
- package/packages/analyze/src/lib/files/analyze/validateDependencyAnalyses.js.map +1 -1
- package/packages/analyze/src/lib/files/analyzeRemixRoute.js +3 -2
- package/packages/analyze/src/lib/files/analyzeRemixRoute.js.map +1 -1
- package/packages/analyze/src/lib/files/getImportedExports.js +11 -7
- package/packages/analyze/src/lib/files/getImportedExports.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js +880 -0
- package/packages/analyze/src/lib/files/scenarios/TransformationTracer.js.map +1 -0
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js +56 -10
- package/packages/analyze/src/lib/files/scenarios/enrichArrayTypesFromChildSignatures.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +33 -8
- package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js +150 -17
- package/packages/analyze/src/lib/files/scenarios/generateDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js +56 -8
- package/packages/analyze/src/lib/files/scenarios/generateExecutionFlows.js.map +1 -1
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +399 -31
- package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
- package/packages/analyze/src/lib/files/setImportedExports.js +2 -1
- package/packages/analyze/src/lib/files/setImportedExports.js.map +1 -1
- package/packages/analyze/src/lib/index.js +1 -0
- package/packages/analyze/src/lib/index.js.map +1 -1
- package/packages/analyze/src/lib/utils/getFileByPath.js +12 -0
- package/packages/analyze/src/lib/utils/getFileByPath.js.map +1 -0
- package/packages/database/src/lib/kysely/db.js +8 -1
- package/packages/database/src/lib/kysely/db.js.map +1 -1
- package/packages/database/src/lib/kysely/tables/commitsTable.js +3 -0
- package/packages/database/src/lib/kysely/tables/commitsTable.js.map +1 -1
- package/packages/database/src/lib/loadAnalyses.js +45 -2
- package/packages/database/src/lib/loadAnalyses.js.map +1 -1
- package/packages/database/src/lib/loadAnalysis.js +8 -0
- package/packages/database/src/lib/loadAnalysis.js.map +1 -1
- package/packages/database/src/lib/loadBranch.js +11 -1
- package/packages/database/src/lib/loadBranch.js.map +1 -1
- package/packages/database/src/lib/loadCommit.js +7 -0
- package/packages/database/src/lib/loadCommit.js.map +1 -1
- package/packages/database/src/lib/loadCommits.js +22 -1
- package/packages/database/src/lib/loadCommits.js.map +1 -1
- package/packages/database/src/lib/loadEntities.js +23 -4
- package/packages/database/src/lib/loadEntities.js.map +1 -1
- package/packages/database/src/lib/loadEntityBranches.js +9 -0
- package/packages/database/src/lib/loadEntityBranches.js.map +1 -1
- package/packages/database/src/lib/updateCommitMetadata.js +5 -4
- package/packages/database/src/lib/updateCommitMetadata.js.map +1 -1
- package/codeyam-cli/src/webserver/build/client/assets/EntityItem-BXhEawa3.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/dev.empty-BRb-0kQl.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/files-Cs4MdYtv.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/git-commit-horizontal-CysbcZxi.js +0 -6
- package/codeyam-cli/src/webserver/build/client/assets/globals-DMUaGAqV.css +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/manifest-f874c610.js +0 -1
- package/codeyam-cli/src/webserver/build/client/assets/root-Bz5TunQg.js +0 -57
- package/codeyam-cli/src/webserver/build/client/assets/rules-hEkvVw2-.js +0 -97
- package/codeyam-cli/src/webserver/build/server/assets/index-967OuJoF.js +0 -1
- package/codeyam-cli/src/webserver/build/server/assets/server-build-DRTmerg9.js +0 -257
- package/codeyam-cli/templates/codeyam:power-rules.md +0 -447
- /package/codeyam-cli/src/webserver/build/client/assets/{api.rules-l0sNRNKZ.js → api.agent-transcripts-l0sNRNKZ.js} +0 -0
package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
/**
|
|
6
|
+
* Create a temporary project directory with the structure expected by rule reflection:
|
|
7
|
+
* - .claude/rules/ (with optional pre-existing rules)
|
|
8
|
+
* - .codeyam/rules/instructions.md
|
|
9
|
+
* - Source files
|
|
10
|
+
* - Git initialized with initial commit
|
|
11
|
+
*/
|
|
12
|
+
export function setupTempProject(options = {}) {
|
|
13
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'codeyam-rule-test-'));
|
|
14
|
+
const rulesDir = path.join(dir, '.claude', 'rules');
|
|
15
|
+
const codeyamRulesDir = path.join(dir, '.codeyam', 'rules');
|
|
16
|
+
// Create directories
|
|
17
|
+
fs.mkdirSync(rulesDir, { recursive: true });
|
|
18
|
+
fs.mkdirSync(codeyamRulesDir, { recursive: true });
|
|
19
|
+
// Write instructions.md
|
|
20
|
+
fs.writeFileSync(path.join(codeyamRulesDir, 'instructions.md'), [
|
|
21
|
+
'# Claude Rules Guide',
|
|
22
|
+
'',
|
|
23
|
+
'Rules provide context-specific guidance.',
|
|
24
|
+
'',
|
|
25
|
+
'## Required Frontmatter',
|
|
26
|
+
'',
|
|
27
|
+
'```yaml',
|
|
28
|
+
'---',
|
|
29
|
+
'paths:',
|
|
30
|
+
" - 'specific/path/to/file.ts'",
|
|
31
|
+
'timestamp: 2026-01-30T00:00:00Z',
|
|
32
|
+
'---',
|
|
33
|
+
'```',
|
|
34
|
+
'',
|
|
35
|
+
'## Content Guidelines',
|
|
36
|
+
'',
|
|
37
|
+
'- One concept per rule',
|
|
38
|
+
'- Be concise',
|
|
39
|
+
'- Focus on non-obvious knowledge',
|
|
40
|
+
].join('\n'));
|
|
41
|
+
// Write existing rules
|
|
42
|
+
for (const [filename, content] of Object.entries(options.existingRules || {})) {
|
|
43
|
+
const filePath = path.join(rulesDir, filename);
|
|
44
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
45
|
+
fs.writeFileSync(filePath, content);
|
|
46
|
+
}
|
|
47
|
+
// Write source files
|
|
48
|
+
for (const [relPath, content] of Object.entries(options.sourceFiles || {})) {
|
|
49
|
+
const filePath = path.join(dir, relPath);
|
|
50
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
51
|
+
fs.writeFileSync(filePath, content);
|
|
52
|
+
}
|
|
53
|
+
// Initialize git repo
|
|
54
|
+
execSync('git init', { cwd: dir, stdio: 'ignore' });
|
|
55
|
+
execSync('git add -A', { cwd: dir, stdio: 'ignore' });
|
|
56
|
+
execSync('git commit -m "initial commit" --allow-empty', {
|
|
57
|
+
cwd: dir,
|
|
58
|
+
stdio: 'ignore',
|
|
59
|
+
env: {
|
|
60
|
+
...process.env,
|
|
61
|
+
GIT_AUTHOR_NAME: 'Test',
|
|
62
|
+
GIT_AUTHOR_EMAIL: 'test@test.com',
|
|
63
|
+
GIT_COMMITTER_NAME: 'Test',
|
|
64
|
+
GIT_COMMITTER_EMAIL: 'test@test.com',
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
dir,
|
|
69
|
+
rulesDir,
|
|
70
|
+
cleanup: () => {
|
|
71
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=setupTempProject.js.map
|
package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setupTempProject.js","sourceRoot":"","sources":["../../../../../../../../src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAazC;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAA8B,EAAE;IAEhC,MAAM,GAAG,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACpD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;IAE5D,qBAAqB;IACrB,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnD,wBAAwB;IACxB,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,iBAAiB,CAAC,EAC7C;QACE,sBAAsB;QACtB,EAAE;QACF,0CAA0C;QAC1C,EAAE;QACF,yBAAyB;QACzB,EAAE;QACF,SAAS;QACT,KAAK;QACL,QAAQ;QACR,gCAAgC;QAChC,iCAAiC;QACjC,KAAK;QACL,KAAK;QACL,EAAE;QACF,uBAAuB;QACvB,EAAE;QACF,wBAAwB;QACxB,cAAc;QACd,kCAAkC;KACnC,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,uBAAuB;IACvB,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAC9C,OAAO,CAAC,aAAa,IAAI,EAAE,CAC5B,EAAE,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/C,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,qBAAqB;IACrB,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC,EAAE,CAAC;QAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACzC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,sBAAsB;IACtB,QAAQ,CAAC,UAAU,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACpD,QAAQ,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACtD,QAAQ,CAAC,8CAA8C,EAAE;QACvD,GAAG,EAAE,GAAG;QACR,KAAK,EAAE,QAAQ;QACf,GAAG,EAAE;YACH,GAAG,OAAO,CAAC,GAAG;YACd,eAAe,EAAE,MAAM;YACvB,gBAAgB,EAAE,eAAe;YACjC,kBAAkB,EAAE,MAAM;YAC1B,mBAAmB,EAAE,eAAe;SACrC;KACF,CAAC,CAAC;IAEH,OAAO;QACL,GAAG;QACH,QAAQ;QACR,OAAO,EAAE,GAAG,EAAE;YACZ,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { setupTempProject } from "./helpers/setupTempProject.js";
|
|
4
|
+
import { snapshotRules, getRulesChanges, assertValidFrontmatter, } from "./helpers/assertRules.js";
|
|
5
|
+
import { runClaude } from "./helpers/runClaude.js";
|
|
6
|
+
import { buildStaleRulesContext, buildConversationContext, } from "../../contextBuilder.js";
|
|
7
|
+
import { buildStaleRulesPrompt, buildConversationPrompt, } from "../../promptBuilder.js";
|
|
8
|
+
const SKIP = !process.env.CODEYAM_RUN_INTEGRATION;
|
|
9
|
+
const OUTPUT_DIR = path.resolve(__dirname, 'output');
|
|
10
|
+
(SKIP ? describe.skip : describe)('Rule Reflection E2E', () => {
|
|
11
|
+
let tempProject;
|
|
12
|
+
afterEach(() => {
|
|
13
|
+
if (tempProject) {
|
|
14
|
+
tempProject.cleanup();
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
it('updates timestamp for stale rule with empty diff', async () => {
|
|
18
|
+
const existingRule = [
|
|
19
|
+
'---',
|
|
20
|
+
'paths:',
|
|
21
|
+
" - 'src/config.ts'",
|
|
22
|
+
'timestamp: 2026-01-01T00:00:00Z',
|
|
23
|
+
'---',
|
|
24
|
+
'',
|
|
25
|
+
'# Build Configuration',
|
|
26
|
+
'',
|
|
27
|
+
'Use `npm run build:prod` for production builds.',
|
|
28
|
+
].join('\n');
|
|
29
|
+
tempProject = setupTempProject({
|
|
30
|
+
existingRules: { 'build-config.md': existingRule },
|
|
31
|
+
sourceFiles: {
|
|
32
|
+
'src/config.ts': 'export const config = { debug: false };',
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
const staleRules = [
|
|
36
|
+
{
|
|
37
|
+
name: 'build-config.md',
|
|
38
|
+
rule_timestamp: '2026-01-01T00:00:00Z',
|
|
39
|
+
newest_file: 'src/config.ts',
|
|
40
|
+
file_modified: '2026-02-01T00:00:00Z',
|
|
41
|
+
diff: '',
|
|
42
|
+
rule_content: '# Build Configuration\n\nUse `npm run build:prod` for production builds.',
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
const contextContent = buildStaleRulesContext(staleRules);
|
|
46
|
+
const contextFile = path.join(tempProject.dir, '.context.md');
|
|
47
|
+
fs.writeFileSync(contextFile, contextContent);
|
|
48
|
+
const notificationFile = path.join(tempProject.dir, 'rule-notification-stale.md');
|
|
49
|
+
const before = await snapshotRules(tempProject.rulesDir);
|
|
50
|
+
const prompt = buildStaleRulesPrompt(contextFile, tempProject.dir, notificationFile);
|
|
51
|
+
runClaude({
|
|
52
|
+
prompt,
|
|
53
|
+
cwd: tempProject.dir,
|
|
54
|
+
saveOutput: { dir: OUTPUT_DIR, label: 'stale-rule-empty-diff' },
|
|
55
|
+
});
|
|
56
|
+
const after = await snapshotRules(tempProject.rulesDir);
|
|
57
|
+
const changes = getRulesChanges(before, after);
|
|
58
|
+
// The rule should be modified (timestamp updated) or unchanged
|
|
59
|
+
// Either way the file should still exist and have valid frontmatter
|
|
60
|
+
const ruleContent = after.files.get('build-config.md') || before.files.get('build-config.md');
|
|
61
|
+
expect(ruleContent).toBeDefined();
|
|
62
|
+
if (changes.modified.includes('build-config.md')) {
|
|
63
|
+
assertValidFrontmatter(ruleContent);
|
|
64
|
+
}
|
|
65
|
+
}, 180000);
|
|
66
|
+
it('creates new rule from user correction conversation', async () => {
|
|
67
|
+
tempProject = setupTempProject({
|
|
68
|
+
sourceFiles: {
|
|
69
|
+
'src/api/auth.ts': 'export function authenticate(req: Request) { /* JWT auth */ }',
|
|
70
|
+
'src/api/session.ts': 'export function createSession() { /* session tokens */ }',
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
const snippets = [
|
|
74
|
+
{
|
|
75
|
+
role: 'user',
|
|
76
|
+
content: 'Update the API endpoint to use the new authentication flow',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
role: 'assistant',
|
|
80
|
+
content: "I'll modify the authentication to use session tokens instead of JWT.",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
role: 'user',
|
|
84
|
+
content: "No, that's not right. We need to keep JWT for the API but add session tokens for the web interface. They work together, not replace each other.",
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
role: 'assistant',
|
|
88
|
+
content: 'I understand now. The JWT tokens remain for API authentication while session tokens are added for the web interface.',
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
const modifiedFiles = new Set([
|
|
92
|
+
['src/api/auth.ts', 'Edit'],
|
|
93
|
+
['src/api/session.ts', 'Write'],
|
|
94
|
+
]);
|
|
95
|
+
const contextContent = buildConversationContext(snippets, modifiedFiles);
|
|
96
|
+
const contextFile = path.join(tempProject.dir, '.context.md');
|
|
97
|
+
fs.writeFileSync(contextFile, contextContent);
|
|
98
|
+
const notificationFile = path.join(tempProject.dir, 'rule-notification-conversation.md');
|
|
99
|
+
const before = await snapshotRules(tempProject.rulesDir);
|
|
100
|
+
const prompt = buildConversationPrompt(contextFile, tempProject.dir, notificationFile);
|
|
101
|
+
runClaude({
|
|
102
|
+
prompt,
|
|
103
|
+
cwd: tempProject.dir,
|
|
104
|
+
saveOutput: { dir: OUTPUT_DIR, label: 'user-correction-conversation' },
|
|
105
|
+
});
|
|
106
|
+
const after = await snapshotRules(tempProject.rulesDir);
|
|
107
|
+
const changes = getRulesChanges(before, after);
|
|
108
|
+
// Should have created at least one new rule about the auth pattern
|
|
109
|
+
expect(changes.created.length).toBeGreaterThan(0);
|
|
110
|
+
// New rule(s) should have valid frontmatter
|
|
111
|
+
for (const created of changes.created) {
|
|
112
|
+
const content = after.files.get(created);
|
|
113
|
+
assertValidFrontmatter(content);
|
|
114
|
+
}
|
|
115
|
+
}, 180000);
|
|
116
|
+
it('handles stale rules and conversation as separate agents', async () => {
|
|
117
|
+
const existingRule = [
|
|
118
|
+
'---',
|
|
119
|
+
'paths:',
|
|
120
|
+
" - 'src/api/auth.ts'",
|
|
121
|
+
'timestamp: 2026-01-15T00:00:00Z',
|
|
122
|
+
'---',
|
|
123
|
+
'',
|
|
124
|
+
'# API Auth',
|
|
125
|
+
'',
|
|
126
|
+
'All API endpoints use JWT authentication.',
|
|
127
|
+
].join('\n');
|
|
128
|
+
tempProject = setupTempProject({
|
|
129
|
+
existingRules: { 'api-auth.md': existingRule },
|
|
130
|
+
sourceFiles: {
|
|
131
|
+
'src/api/auth.ts': 'export function authenticate() {}',
|
|
132
|
+
'src/utils/helpers.ts': 'export function helper() {}',
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
const staleRules = [
|
|
136
|
+
{
|
|
137
|
+
name: 'api-auth.md',
|
|
138
|
+
rule_timestamp: '2026-01-15T00:00:00Z',
|
|
139
|
+
newest_file: 'src/api/auth.ts',
|
|
140
|
+
file_modified: '2026-02-01T00:00:00Z',
|
|
141
|
+
diff: '@@ -1 +1,2 @@\n+import { validateSession } from "./session.js"\n export function authenticate() {}',
|
|
142
|
+
rule_content: '# API Auth\n\nAll API endpoints use JWT authentication.',
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
const snippets = [
|
|
146
|
+
{
|
|
147
|
+
role: 'user',
|
|
148
|
+
content: 'The helpers module needs to be imported before auth because of initialization order',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
role: 'assistant',
|
|
152
|
+
content: 'I see, there is an initialization dependency between helpers and auth.',
|
|
153
|
+
},
|
|
154
|
+
];
|
|
155
|
+
const notificationFileStale = path.join(tempProject.dir, 'rule-notification-stale.md');
|
|
156
|
+
const notificationFileConv = path.join(tempProject.dir, 'rule-notification-conversation.md');
|
|
157
|
+
// Run stale rules agent
|
|
158
|
+
const staleContext = buildStaleRulesContext(staleRules);
|
|
159
|
+
const staleContextFile = path.join(tempProject.dir, '.context-stale.md');
|
|
160
|
+
fs.writeFileSync(staleContextFile, staleContext);
|
|
161
|
+
const before = await snapshotRules(tempProject.rulesDir);
|
|
162
|
+
const stalePrompt = buildStaleRulesPrompt(staleContextFile, tempProject.dir, notificationFileStale);
|
|
163
|
+
runClaude({
|
|
164
|
+
prompt: stalePrompt,
|
|
165
|
+
cwd: tempProject.dir,
|
|
166
|
+
saveOutput: { dir: OUTPUT_DIR, label: 'combined-stale' },
|
|
167
|
+
});
|
|
168
|
+
// Run conversation agent
|
|
169
|
+
const convContext = buildConversationContext(snippets, new Set());
|
|
170
|
+
const convContextFile = path.join(tempProject.dir, '.context-conversation.md');
|
|
171
|
+
fs.writeFileSync(convContextFile, convContext);
|
|
172
|
+
const convPrompt = buildConversationPrompt(convContextFile, tempProject.dir, notificationFileConv);
|
|
173
|
+
runClaude({
|
|
174
|
+
prompt: convPrompt,
|
|
175
|
+
cwd: tempProject.dir,
|
|
176
|
+
saveOutput: { dir: OUTPUT_DIR, label: 'combined-conversation' },
|
|
177
|
+
});
|
|
178
|
+
const after = await snapshotRules(tempProject.rulesDir);
|
|
179
|
+
const changes = getRulesChanges(before, after);
|
|
180
|
+
// Existing rule should still be present
|
|
181
|
+
expect(after.files.has('api-auth.md')).toBe(true);
|
|
182
|
+
// Total changes (stale rule update + potential new rule) should be > 0
|
|
183
|
+
expect(changes.modified.length + changes.created.length).toBeGreaterThan(0);
|
|
184
|
+
}, 300000);
|
|
185
|
+
it('writes notification file when rules change', async () => {
|
|
186
|
+
tempProject = setupTempProject({
|
|
187
|
+
sourceFiles: {
|
|
188
|
+
'src/index.ts': 'console.log("hello");',
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
const snippets = [
|
|
192
|
+
{
|
|
193
|
+
role: 'user',
|
|
194
|
+
content: "No, that's wrong. You must always run the linter before committing. The pre-commit hook checks this.",
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
role: 'assistant',
|
|
198
|
+
content: 'I see, the pre-commit hook enforces linting. I will run the linter first.',
|
|
199
|
+
},
|
|
200
|
+
];
|
|
201
|
+
const contextContent = buildConversationContext(snippets, new Set());
|
|
202
|
+
const contextFile = path.join(tempProject.dir, '.context.md');
|
|
203
|
+
fs.writeFileSync(contextFile, contextContent);
|
|
204
|
+
const notificationFile = path.join(tempProject.dir, 'rule-notification-conversation.md');
|
|
205
|
+
const prompt = buildConversationPrompt(contextFile, tempProject.dir, notificationFile);
|
|
206
|
+
runClaude({
|
|
207
|
+
prompt,
|
|
208
|
+
cwd: tempProject.dir,
|
|
209
|
+
saveOutput: { dir: OUTPUT_DIR, label: 'notification-file' },
|
|
210
|
+
});
|
|
211
|
+
const after = await snapshotRules(tempProject.rulesDir);
|
|
212
|
+
// If rules were created, notification should exist
|
|
213
|
+
if (after.files.size > 0) {
|
|
214
|
+
expect(fs.existsSync(notificationFile)).toBe(true);
|
|
215
|
+
const notification = fs.readFileSync(notificationFile, 'utf-8');
|
|
216
|
+
expect(notification.length).toBeGreaterThan(0);
|
|
217
|
+
}
|
|
218
|
+
}, 180000);
|
|
219
|
+
describe('captured fixtures', () => {
|
|
220
|
+
const FIXTURES_DIR = path.resolve(__dirname, '../fixtures/captured');
|
|
221
|
+
it('does not create rules from routine implementation conversation (fe1a8b55)', async () => {
|
|
222
|
+
// This fixture captured a session where the user asked to reorder search
|
|
223
|
+
// results in the memory audit section. It was purely implementation work
|
|
224
|
+
// with no user corrections, confusion, or architectural decisions.
|
|
225
|
+
// The agent incorrectly created a rule about search ordering.
|
|
226
|
+
//
|
|
227
|
+
// We rebuild the context using the CURRENT guidance template + the
|
|
228
|
+
// fixture's transcript so that guidance improvements are tested.
|
|
229
|
+
tempProject = setupTempProject({
|
|
230
|
+
sourceFiles: {
|
|
231
|
+
'src/webserver/app/components/memory/MemoryAuditSection.tsx': 'export function MemoryAuditSection() { return <div />; }',
|
|
232
|
+
'src/webserver/app/lib/memory/types.ts': 'export interface AuditData { topPaths: any[]; allSourceFiles: string[]; }',
|
|
233
|
+
'src/webserver/app/routes/api.memory.ts': 'export async function loader() { return Response.json({}); }',
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
// Transcript from the captured fixture — the user gave clear
|
|
237
|
+
// implementation requirements, no corrections or confusion.
|
|
238
|
+
const snippets = [
|
|
239
|
+
{
|
|
240
|
+
role: 'user',
|
|
241
|
+
content: 'Ok can we order the results by path that start with the search string, followed by paths that contain the search string? Within those matches it should be alphabetic. The search results order should not be impacted by the rule count or token count at all. All files in the repo should be included in the search',
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
role: 'assistant',
|
|
245
|
+
content: 'Let me look at the current data flow to understand what needs to change.',
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
role: 'assistant',
|
|
249
|
+
content: "The API only returns files that have matching rules. I need to also return all source files so search can cover everything. But sending full coverage data for every file would be heavy — I'll return the source file list separately and build search results client-side.",
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
role: 'assistant',
|
|
253
|
+
content: 'Now update the search suggestions to use all source files with proper sorting, and build `PathCoverage` entries on the fly for files without rule coverage.',
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
role: 'assistant',
|
|
257
|
+
content: "Builds clean. Here's what changed: 1. All files searchable: API now returns allSourceFiles 2. Sorting: Prefix matches first, then contains — alphabetical within each group 3. No rule/token bias: Sorting is purely by path 4. Overflow fix: Removed overflow-hidden so the dropdown isn't clipped",
|
|
258
|
+
},
|
|
259
|
+
];
|
|
260
|
+
const modifiedFiles = new Set([
|
|
261
|
+
['src/webserver/app/components/memory/MemoryAuditSection.tsx', 'Edit'],
|
|
262
|
+
['src/webserver/app/lib/memory/types.ts', 'Edit'],
|
|
263
|
+
['src/webserver/app/routes/api.memory.ts', 'Edit'],
|
|
264
|
+
]);
|
|
265
|
+
const contextContent = buildConversationContext(snippets, modifiedFiles);
|
|
266
|
+
const contextFile = path.join(tempProject.dir, '.context.md');
|
|
267
|
+
fs.writeFileSync(contextFile, contextContent);
|
|
268
|
+
const notificationFile = path.join(tempProject.dir, 'rule-notification-conversation.md');
|
|
269
|
+
const before = await snapshotRules(tempProject.rulesDir);
|
|
270
|
+
const prompt = buildConversationPrompt(contextFile, tempProject.dir, notificationFile);
|
|
271
|
+
runClaude({
|
|
272
|
+
prompt,
|
|
273
|
+
cwd: tempProject.dir,
|
|
274
|
+
saveOutput: { dir: OUTPUT_DIR, label: 'fixture-fe1a8b55-no-rule' },
|
|
275
|
+
});
|
|
276
|
+
const after = await snapshotRules(tempProject.rulesDir);
|
|
277
|
+
const changes = getRulesChanges(before, after);
|
|
278
|
+
// No rules should be created — this was routine implementation work.
|
|
279
|
+
// The user gave clear instructions about search ordering; there were
|
|
280
|
+
// no corrections, confusion, or non-obvious architectural decisions.
|
|
281
|
+
expect(changes.created.length).toBe(0);
|
|
282
|
+
}, 180000);
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
//# sourceMappingURL=ruleReflectionE2E.test.js.map
|
package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruleReflectionE2E.test.js","sourceRoot":"","sources":["../../../../../../../src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { buildStaleRulesPrompt, buildConversationPrompt, buildInterruptionPrompt, } from "../promptBuilder.js";
|
|
2
|
+
describe('promptBuilder', () => {
|
|
3
|
+
describe('buildStaleRulesPrompt', () => {
|
|
4
|
+
const contextFile = '/tmp/claude-rule-markers/abc123-stale.context';
|
|
5
|
+
const projectDir = '/home/user/my-project';
|
|
6
|
+
const notificationFile = '/tmp/claude-rule-markers/rule-notification-stale.md';
|
|
7
|
+
let prompt;
|
|
8
|
+
beforeAll(() => {
|
|
9
|
+
prompt = buildStaleRulesPrompt(contextFile, projectDir, notificationFile);
|
|
10
|
+
});
|
|
11
|
+
it('references instructions.md', () => {
|
|
12
|
+
expect(prompt).toContain('.codeyam/rules/instructions.md');
|
|
13
|
+
});
|
|
14
|
+
it('includes context file path', () => {
|
|
15
|
+
expect(prompt).toContain(contextFile);
|
|
16
|
+
});
|
|
17
|
+
it('includes notification file path', () => {
|
|
18
|
+
expect(prompt).toContain(notificationFile);
|
|
19
|
+
});
|
|
20
|
+
it('includes project dir', () => {
|
|
21
|
+
expect(prompt).toContain(`The project root is ${projectDir}`);
|
|
22
|
+
});
|
|
23
|
+
it('includes codeyam memory touch instruction', () => {
|
|
24
|
+
expect(prompt).toContain('codeyam memory touch');
|
|
25
|
+
});
|
|
26
|
+
it('instructs to read instructions.md first', () => {
|
|
27
|
+
const firstIdx = prompt.indexOf('.codeyam/rules/instructions.md');
|
|
28
|
+
const contextIdx = prompt.indexOf(contextFile);
|
|
29
|
+
expect(firstIdx).toBeLessThan(contextIdx);
|
|
30
|
+
});
|
|
31
|
+
it('includes stale rule review steps', () => {
|
|
32
|
+
expect(prompt).toContain('Review the inline rule content and the diff');
|
|
33
|
+
expect(prompt).toContain("If the diff is empty or doesn't affect the rule, just run `codeyam memory touch`");
|
|
34
|
+
expect(prompt).toContain('edit the rule file in .claude/rules/');
|
|
35
|
+
});
|
|
36
|
+
it('includes notification format example', () => {
|
|
37
|
+
expect(prompt).toContain('The background rule-reflection agent updated the following rules:');
|
|
38
|
+
});
|
|
39
|
+
it('instructs to still notify for timestamp-only changes', () => {
|
|
40
|
+
expect(prompt).toContain('If you only touched timestamps without content changes, still write the notification.');
|
|
41
|
+
});
|
|
42
|
+
it('instructs not to write notification when no changes', () => {
|
|
43
|
+
expect(prompt).toContain('If no rules were changed at all, do NOT write the notification file.');
|
|
44
|
+
});
|
|
45
|
+
it('does NOT mention conversation analysis', () => {
|
|
46
|
+
expect(prompt).not.toContain('conversation review section');
|
|
47
|
+
expect(prompt).not.toContain('Analyze the conversation transcript');
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
describe('buildConversationPrompt', () => {
|
|
51
|
+
const contextFile = '/tmp/claude-rule-markers/abc123-conversation.context';
|
|
52
|
+
const projectDir = '/home/user/my-project';
|
|
53
|
+
const notificationFile = '/tmp/claude-rule-markers/rule-notification-conversation.md';
|
|
54
|
+
let prompt;
|
|
55
|
+
beforeAll(() => {
|
|
56
|
+
prompt = buildConversationPrompt(contextFile, projectDir, notificationFile);
|
|
57
|
+
});
|
|
58
|
+
it('references instructions.md', () => {
|
|
59
|
+
expect(prompt).toContain('.codeyam/rules/instructions.md');
|
|
60
|
+
});
|
|
61
|
+
it('includes context file path', () => {
|
|
62
|
+
expect(prompt).toContain(contextFile);
|
|
63
|
+
});
|
|
64
|
+
it('includes notification file path', () => {
|
|
65
|
+
expect(prompt).toContain(notificationFile);
|
|
66
|
+
});
|
|
67
|
+
it('includes project dir', () => {
|
|
68
|
+
expect(prompt).toContain(`The project root is ${projectDir}`);
|
|
69
|
+
});
|
|
70
|
+
it('mentions conversation analysis topics', () => {
|
|
71
|
+
expect(prompt).toContain('Analyze the conversation transcript');
|
|
72
|
+
expect(prompt).toContain('User corrections');
|
|
73
|
+
expect(prompt).toContain('Investigation results');
|
|
74
|
+
expect(prompt).toContain('Architecture and relationships');
|
|
75
|
+
});
|
|
76
|
+
it('does NOT mention stale rule review steps', () => {
|
|
77
|
+
expect(prompt).not.toContain('Review the inline rule content and the diff');
|
|
78
|
+
expect(prompt).not.toContain('codeyam memory touch');
|
|
79
|
+
expect(prompt).not.toContain("If the diff is empty or doesn't affect the rule");
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
describe('buildInterruptionPrompt', () => {
|
|
83
|
+
const contextFile = '/tmp/claude-rule-markers/abc123-interruption.context';
|
|
84
|
+
const projectDir = '/home/user/my-project';
|
|
85
|
+
const notificationFile = '/tmp/claude-rule-markers/rule-notification-interruption.md';
|
|
86
|
+
let prompt;
|
|
87
|
+
beforeAll(() => {
|
|
88
|
+
prompt = buildInterruptionPrompt(contextFile, projectDir, notificationFile);
|
|
89
|
+
});
|
|
90
|
+
it('references instructions.md', () => {
|
|
91
|
+
expect(prompt).toContain('.codeyam/rules/instructions.md');
|
|
92
|
+
});
|
|
93
|
+
it('includes context file path', () => {
|
|
94
|
+
expect(prompt).toContain(contextFile);
|
|
95
|
+
});
|
|
96
|
+
it('includes notification file path', () => {
|
|
97
|
+
expect(prompt).toContain(notificationFile);
|
|
98
|
+
});
|
|
99
|
+
it('includes project dir', () => {
|
|
100
|
+
expect(prompt).toContain(`The project root is ${projectDir}`);
|
|
101
|
+
});
|
|
102
|
+
it('mentions interruption as a strong confusion signal', () => {
|
|
103
|
+
expect(prompt).toContain('interrupted Claude mid-response');
|
|
104
|
+
});
|
|
105
|
+
it('mentions analyzing both interrupted output and follow-up', () => {
|
|
106
|
+
expect(prompt).toContain('interrupted output');
|
|
107
|
+
expect(prompt).toContain('follow-up');
|
|
108
|
+
});
|
|
109
|
+
it('does NOT mention stale rule review steps', () => {
|
|
110
|
+
expect(prompt).not.toContain('Review the inline rule content and the diff');
|
|
111
|
+
expect(prompt).not.toContain('codeyam memory touch');
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=promptBuilder.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promptBuilder.test.js","sourceRoot":"","sources":["../../../../../../src/utils/ruleReflection/__tests__/promptBuilder.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { parseTranscript } from "../transcriptParser.js";
|
|
4
|
+
const fixturesDir = path.join(__dirname, 'fixtures');
|
|
5
|
+
function loadFixture(name) {
|
|
6
|
+
return fs.readFileSync(path.join(fixturesDir, name), 'utf-8');
|
|
7
|
+
}
|
|
8
|
+
describe('transcriptParser', () => {
|
|
9
|
+
describe('parseTranscript', () => {
|
|
10
|
+
it('returns empty results for empty input', () => {
|
|
11
|
+
const result = parseTranscript('');
|
|
12
|
+
expect(result.userTurnCount).toBe(0);
|
|
13
|
+
expect(result.snippets).toEqual([]);
|
|
14
|
+
expect(result.modifiedFiles.size).toBe(0);
|
|
15
|
+
expect(result.currentLineCount).toBe(0);
|
|
16
|
+
});
|
|
17
|
+
it('returns empty results for empty-session fixture', () => {
|
|
18
|
+
const content = loadFixture('empty-session.jsonl');
|
|
19
|
+
const result = parseTranscript(content);
|
|
20
|
+
// Only a system message, no user/assistant
|
|
21
|
+
expect(result.userTurnCount).toBe(0);
|
|
22
|
+
expect(result.snippets).toEqual([]);
|
|
23
|
+
});
|
|
24
|
+
it('extracts snippets from simple session', () => {
|
|
25
|
+
const content = loadFixture('simple-session.jsonl');
|
|
26
|
+
const result = parseTranscript(content);
|
|
27
|
+
expect(result.userTurnCount).toBe(2);
|
|
28
|
+
expect(result.snippets.length).toBeGreaterThan(0);
|
|
29
|
+
// Should have user messages
|
|
30
|
+
const userSnippets = result.snippets.filter((s) => s.role === 'user');
|
|
31
|
+
expect(userSnippets.length).toBeGreaterThan(0);
|
|
32
|
+
expect(userSnippets[0].content).toContain('logout button');
|
|
33
|
+
});
|
|
34
|
+
it('tracks modified files from Edit/Write tool_use', () => {
|
|
35
|
+
const content = loadFixture('simple-session.jsonl');
|
|
36
|
+
const result = parseTranscript(content);
|
|
37
|
+
const modifiedArray = Array.from(result.modifiedFiles);
|
|
38
|
+
expect(modifiedArray.length).toBe(1);
|
|
39
|
+
expect(modifiedArray[0]).toEqual(['src/components/NavBar.tsx', 'Edit']);
|
|
40
|
+
});
|
|
41
|
+
it('tracks both Edit and Write tool uses', () => {
|
|
42
|
+
const content = loadFixture('user-correction.jsonl');
|
|
43
|
+
const result = parseTranscript(content);
|
|
44
|
+
const modifiedArray = Array.from(result.modifiedFiles);
|
|
45
|
+
const filePaths = modifiedArray.map(([p]) => p);
|
|
46
|
+
expect(filePaths).toContain('src/api/auth.ts');
|
|
47
|
+
expect(filePaths).toContain('src/api/sessionAuth.ts');
|
|
48
|
+
const toolNames = modifiedArray.map(([, t]) => t);
|
|
49
|
+
expect(toolNames).toContain('Edit');
|
|
50
|
+
expect(toolNames).toContain('Write');
|
|
51
|
+
});
|
|
52
|
+
it('counts user turns from external users only', () => {
|
|
53
|
+
const content = loadFixture('user-correction.jsonl');
|
|
54
|
+
const result = parseTranscript(content);
|
|
55
|
+
// 3 external user messages in the fixture
|
|
56
|
+
expect(result.userTurnCount).toBe(3);
|
|
57
|
+
});
|
|
58
|
+
it('respects lastLine offset', () => {
|
|
59
|
+
const content = loadFixture('simple-session.jsonl');
|
|
60
|
+
// Parse all lines first
|
|
61
|
+
const fullResult = parseTranscript(content);
|
|
62
|
+
const totalLines = fullResult.currentLineCount;
|
|
63
|
+
// Parse with offset past all lines
|
|
64
|
+
const offsetResult = parseTranscript(content, totalLines);
|
|
65
|
+
expect(offsetResult.userTurnCount).toBe(0);
|
|
66
|
+
expect(offsetResult.snippets).toEqual([]);
|
|
67
|
+
});
|
|
68
|
+
it('returns correct currentLineCount', () => {
|
|
69
|
+
const content = loadFixture('simple-session.jsonl');
|
|
70
|
+
const result = parseTranscript(content);
|
|
71
|
+
const expectedLines = content.split('\n').filter((l) => l.trim()).length;
|
|
72
|
+
expect(result.currentLineCount).toBe(expectedLines);
|
|
73
|
+
});
|
|
74
|
+
it('skips malformed JSON lines gracefully', () => {
|
|
75
|
+
const content = '{"type":"user","userType":"external","message":{"role":"user","content":"Hello this is a valid message"}}\nnot valid json\n{"type":"assistant","message":{"role":"assistant","content":"Thanks for reaching out, how can I help?"}}';
|
|
76
|
+
const result = parseTranscript(content);
|
|
77
|
+
// Should have parsed the valid lines
|
|
78
|
+
expect(result.snippets.length).toBe(2);
|
|
79
|
+
});
|
|
80
|
+
it('skips messages with isMeta flag', () => {
|
|
81
|
+
const content = '{"type":"user","isMeta":true,"message":{"role":"user","content":"This is a meta message with enough length"}}';
|
|
82
|
+
const result = parseTranscript(content);
|
|
83
|
+
expect(result.snippets).toEqual([]);
|
|
84
|
+
});
|
|
85
|
+
it('skips short string content (< 20 chars)', () => {
|
|
86
|
+
const content = '{"type":"user","userType":"external","message":{"role":"user","content":"ok"}}';
|
|
87
|
+
const result = parseTranscript(content);
|
|
88
|
+
expect(result.snippets).toEqual([]);
|
|
89
|
+
expect(result.userTurnCount).toBe(0);
|
|
90
|
+
});
|
|
91
|
+
it('skips content starting with [{ or containing <tool_result', () => {
|
|
92
|
+
const lines = [
|
|
93
|
+
'{"type":"user","message":{"role":"user","content":"[{something json-like content here}]"}}',
|
|
94
|
+
'{"type":"user","message":{"role":"user","content":"some text <tool_result>blah</tool_result> more text"}}',
|
|
95
|
+
];
|
|
96
|
+
const result = parseTranscript(lines.join('\n'));
|
|
97
|
+
expect(result.snippets).toEqual([]);
|
|
98
|
+
});
|
|
99
|
+
it('does not count user turns for messages starting with <', () => {
|
|
100
|
+
const content = '{"type":"user","userType":"external","message":{"role":"user","content":"<system>This is a system-injected message with enough length</system>"}}';
|
|
101
|
+
const result = parseTranscript(content);
|
|
102
|
+
// Should still create a snippet but not count as user turn
|
|
103
|
+
expect(result.userTurnCount).toBe(0);
|
|
104
|
+
expect(result.snippets.length).toBe(1);
|
|
105
|
+
});
|
|
106
|
+
it('extracts text from list content items', () => {
|
|
107
|
+
const content = loadFixture('debugging-session.jsonl');
|
|
108
|
+
const result = parseTranscript(content);
|
|
109
|
+
const assistantSnippets = result.snippets.filter((s) => s.role === 'assistant');
|
|
110
|
+
expect(assistantSnippets.length).toBeGreaterThan(0);
|
|
111
|
+
// Should have extracted text from the text content items
|
|
112
|
+
expect(assistantSnippets.some((s) => s.content.includes('circular dependency'))).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
it('skips text content items shorter than 20 chars', () => {
|
|
115
|
+
const content = JSON.stringify({
|
|
116
|
+
type: 'assistant',
|
|
117
|
+
message: {
|
|
118
|
+
role: 'assistant',
|
|
119
|
+
content: [{ type: 'text', text: 'short' }],
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
const result = parseTranscript(content);
|
|
123
|
+
expect(result.snippets).toEqual([]);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=transcriptParser.test.js.map
|