@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.
Files changed (185) hide show
  1. package/analyzer-template/.build-info.json +7 -7
  2. package/analyzer-template/log.txt +3 -3
  3. package/analyzer-template/package.json +13 -13
  4. package/analyzer-template/packages/ai/index.ts +1 -0
  5. package/analyzer-template/packages/ai/src/lib/analyzeScope.ts +14 -0
  6. package/analyzer-template/packages/ai/src/lib/dataStructure/ScopeDataStructure.ts +232 -5
  7. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.ts +29 -18
  8. package/analyzer-template/packages/ai/src/lib/dataStructure/helpers/stripNullableMarkers.ts +35 -0
  9. package/analyzer-template/packages/ai/src/lib/dataStructureChunking.ts +15 -6
  10. package/analyzer-template/packages/ai/src/lib/generateExecutionFlows.ts +96 -0
  11. package/analyzer-template/packages/analyze/src/lib/asts/nodes/getNodeType.ts +1 -0
  12. package/analyzer-template/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.ts +18 -0
  13. package/analyzer-template/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.ts +50 -25
  14. package/analyzer-template/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.ts +153 -76
  15. package/analyzer-template/packages/aws/package.json +10 -10
  16. package/analyzer-template/packages/database/src/lib/kysely/tables/debugReportsTable.ts +1 -1
  17. package/analyzer-template/packages/github/dist/database/src/lib/kysely/tables/debugReportsTable.d.ts +1 -1
  18. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.d.ts.map +1 -1
  19. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js +98 -3
  20. package/analyzer-template/packages/utils/dist/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  21. package/analyzer-template/packages/utils/src/lib/fs/rsyncCopy.ts +121 -3
  22. package/analyzer-template/project/constructMockCode.ts +34 -7
  23. package/analyzer-template/project/orchestrateCapture.ts +4 -1
  24. package/analyzer-template/project/writeScenarioComponents.ts +76 -12
  25. package/background/src/lib/virtualized/project/constructMockCode.js +30 -7
  26. package/background/src/lib/virtualized/project/constructMockCode.js.map +1 -1
  27. package/background/src/lib/virtualized/project/orchestrateCapture.js +4 -1
  28. package/background/src/lib/virtualized/project/orchestrateCapture.js.map +1 -1
  29. package/background/src/lib/virtualized/project/writeScenarioComponents.js +56 -7
  30. package/background/src/lib/virtualized/project/writeScenarioComponents.js.map +1 -1
  31. package/codeyam-cli/scripts/apply-setup.js +1 -1
  32. package/codeyam-cli/src/cli.js +31 -20
  33. package/codeyam-cli/src/cli.js.map +1 -1
  34. package/codeyam-cli/src/commands/analyze.js +2 -2
  35. package/codeyam-cli/src/commands/analyze.js.map +1 -1
  36. package/codeyam-cli/src/commands/default.js +6 -1
  37. package/codeyam-cli/src/commands/default.js.map +1 -1
  38. package/codeyam-cli/src/commands/memory.js +64 -74
  39. package/codeyam-cli/src/commands/memory.js.map +1 -1
  40. package/codeyam-cli/src/commands/setup-simulations.js +1 -1
  41. package/codeyam-cli/src/commands/verify.js +12 -2
  42. package/codeyam-cli/src/commands/verify.js.map +1 -1
  43. package/codeyam-cli/src/utils/__tests__/npmVersionCheck.test.js +185 -0
  44. package/codeyam-cli/src/utils/__tests__/npmVersionCheck.test.js.map +1 -0
  45. package/codeyam-cli/src/utils/__tests__/setupClaudeCodeSettings.test.js +11 -11
  46. package/codeyam-cli/src/utils/backgroundServer.js +90 -23
  47. package/codeyam-cli/src/utils/backgroundServer.js.map +1 -1
  48. package/codeyam-cli/src/utils/generateReport.js +2 -2
  49. package/codeyam-cli/src/utils/install-skills.js +13 -13
  50. package/codeyam-cli/src/utils/labsAutoCheck.js +0 -29
  51. package/codeyam-cli/src/utils/labsAutoCheck.js.map +1 -1
  52. package/codeyam-cli/src/utils/npmVersionCheck.js +76 -0
  53. package/codeyam-cli/src/utils/npmVersionCheck.js.map +1 -0
  54. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js +1 -1
  55. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/assertRules.js.map +1 -1
  56. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js +0 -1
  57. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/helpers/setupTempProject.js.map +1 -1
  58. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js +2 -4
  59. package/codeyam-cli/src/utils/ruleReflection/__tests__/integration/ruleReflectionE2E.test.js.map +1 -1
  60. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js +2 -1
  61. package/codeyam-cli/src/utils/ruleReflection/__tests__/promptBuilder.test.js.map +1 -1
  62. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js +1 -1
  63. package/codeyam-cli/src/utils/ruleReflection/contextBuilder.js.map +1 -1
  64. package/codeyam-cli/src/utils/rules/__tests__/parser.test.js +83 -0
  65. package/codeyam-cli/src/utils/rules/__tests__/parser.test.js.map +1 -0
  66. package/codeyam-cli/src/utils/rules/__tests__/pathMatcher.test.js +118 -0
  67. package/codeyam-cli/src/utils/rules/__tests__/pathMatcher.test.js.map +1 -0
  68. package/codeyam-cli/src/utils/rules/__tests__/sourceFiles.test.js +83 -0
  69. package/codeyam-cli/src/utils/rules/__tests__/sourceFiles.test.js.map +1 -0
  70. package/codeyam-cli/src/utils/rules/index.js +1 -0
  71. package/codeyam-cli/src/utils/rules/index.js.map +1 -1
  72. package/codeyam-cli/src/utils/rules/parser.js +14 -4
  73. package/codeyam-cli/src/utils/rules/parser.js.map +1 -1
  74. package/codeyam-cli/src/utils/rules/pathMatcher.js +34 -3
  75. package/codeyam-cli/src/utils/rules/pathMatcher.js.map +1 -1
  76. package/codeyam-cli/src/utils/rules/sourceFiles.js +47 -0
  77. package/codeyam-cli/src/utils/rules/sourceFiles.js.map +1 -0
  78. package/codeyam-cli/src/utils/setupClaudeCodeSettings.js +7 -7
  79. package/codeyam-cli/src/utils/simulationGateMiddleware.js +138 -0
  80. package/codeyam-cli/src/utils/simulationGateMiddleware.js.map +1 -0
  81. package/codeyam-cli/src/utils/syncMocksMiddleware.js +5 -24
  82. package/codeyam-cli/src/utils/syncMocksMiddleware.js.map +1 -1
  83. package/codeyam-cli/src/utils/versionInfo.js +46 -0
  84. package/codeyam-cli/src/utils/versionInfo.js.map +1 -1
  85. package/codeyam-cli/src/webserver/__tests__/dependency-smoke.test.js +66 -0
  86. package/codeyam-cli/src/webserver/__tests__/dependency-smoke.test.js.map +1 -0
  87. package/codeyam-cli/src/webserver/app/lib/dbNotifier.js.map +1 -1
  88. package/codeyam-cli/src/webserver/backgroundServer.js +26 -7
  89. package/codeyam-cli/src/webserver/backgroundServer.js.map +1 -1
  90. package/codeyam-cli/src/webserver/bootstrap.js +11 -0
  91. package/codeyam-cli/src/webserver/bootstrap.js.map +1 -1
  92. package/codeyam-cli/src/webserver/build/client/assets/{CopyButton-CA3JxPb7.js → CopyButton-jNYXRRNI.js} +1 -1
  93. package/codeyam-cli/src/webserver/build/client/assets/{EntityItem-B86KKU7e.js → EntityItem-bwuHPyTa.js} +1 -1
  94. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeBadge-B5ctlSYt.js → EntityTypeBadge-CvzqMxcu.js} +1 -1
  95. package/codeyam-cli/src/webserver/build/client/assets/{EntityTypeIcon-BqY8gDAW.js → EntityTypeIcon-BH0XDim7.js} +1 -1
  96. package/codeyam-cli/src/webserver/build/client/assets/{InlineSpinner-ClaLpuOo.js → InlineSpinner-EhOseatT.js} +1 -1
  97. package/codeyam-cli/src/webserver/build/client/assets/{InteractivePreview-BDhPilK7.js → InteractivePreview-yjIHlOGa.js} +2 -2
  98. package/codeyam-cli/src/webserver/build/client/assets/{LibraryFunctionPreview-VeqEBv9v.js → LibraryFunctionPreview-Cq5o8jL4.js} +1 -1
  99. package/codeyam-cli/src/webserver/build/client/assets/{LoadingDots-Bs7Nn1Jr.js → LoadingDots-BvMu2i-g.js} +1 -1
  100. package/codeyam-cli/src/webserver/build/client/assets/{LogViewer-Bm3PmcCz.js → LogViewer-kgBTLoJD.js} +1 -1
  101. package/codeyam-cli/src/webserver/build/client/assets/{ReportIssueModal-C6PKeMYR.js → ReportIssueModal-BzPgx-xO.js} +2 -2
  102. package/codeyam-cli/src/webserver/build/client/assets/{SafeScreenshot-Gq3Ocjo6.js → SafeScreenshot-CwZrv-Ok.js} +1 -1
  103. package/codeyam-cli/src/webserver/build/client/assets/{ScenarioViewer-BNLaXBHR.js → ScenarioViewer-BX2Ny2Qj.js} +2 -2
  104. package/codeyam-cli/src/webserver/build/client/assets/{TruncatedFilePath-CiwXDxLh.js → TruncatedFilePath-CDpEprKa.js} +1 -1
  105. package/codeyam-cli/src/webserver/build/client/assets/{_index-B3TDXxnk.js → _index-BRx8ZGZo.js} +1 -1
  106. package/codeyam-cli/src/webserver/build/client/assets/{activity.(_tab)-BtBFH820.js → activity.(_tab)-4S4yPfFw.js} +1 -1
  107. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-DHKuQSmR.js +17 -0
  108. package/codeyam-cli/src/webserver/build/client/assets/{book-open-PttOB2SF.js → book-open-D4IPYH_y.js} +1 -1
  109. package/codeyam-cli/src/webserver/build/client/assets/{chevron-down-TJp6ofnp.js → chevron-down-CG65viiV.js} +1 -1
  110. package/codeyam-cli/src/webserver/build/client/assets/{chunk-JZWAC4HX-JE9ZIoBl.js → chunk-JZWAC4HX-DB3aFuEO.js} +9 -9
  111. package/codeyam-cli/src/webserver/build/client/assets/{circle-check-CXhHQYrI.js → circle-check-igfMr5DY.js} +1 -1
  112. package/codeyam-cli/src/webserver/build/client/assets/{copy-6y9ALfGT.js → copy-Coc4o_8c.js} +1 -1
  113. package/codeyam-cli/src/webserver/build/client/assets/{createLucideIcon-Ca9fAY46.js → createLucideIcon-D1zB-pYc.js} +1 -1
  114. package/codeyam-cli/src/webserver/build/client/assets/{dev.empty-C5lqplTC.js → dev.empty-JTAjQ54M.js} +1 -1
  115. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha._-n38keI1k.js → entity._sha._-B0h9AqE6.js} +2 -2
  116. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha.scenarios._scenarioId.fullscreen-CBoafmVs.js → entity._sha.scenarios._scenarioId.fullscreen-DjLxr2JB.js} +1 -1
  117. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.create-scenario-DGgZjdFg.js → entity._sha_.create-scenario-CtYowLOt.js} +1 -1
  118. package/codeyam-cli/src/webserver/build/client/assets/{entity._sha_.edit._scenarioId-38yPijoD.js → entity._sha_.edit._scenarioId-PePWg17F.js} +1 -1
  119. package/codeyam-cli/src/webserver/build/client/assets/{entry.client-BSHEfydn.js → entry.client-I-Wo99C_.js} +1 -1
  120. package/codeyam-cli/src/webserver/build/client/assets/{fileTableUtils-DCPhhSMo.js → fileTableUtils-9sMMAiWJ.js} +1 -1
  121. package/codeyam-cli/src/webserver/build/client/assets/{files-0N0YJQv7.js → files-Co65J0s3.js} +1 -1
  122. package/codeyam-cli/src/webserver/build/client/assets/{git-DXnyr8uP.js → git-BdHOxVfg.js} +1 -1
  123. package/codeyam-cli/src/webserver/build/client/assets/globals-B4MPiL7S.css +1 -0
  124. package/codeyam-cli/src/webserver/build/client/assets/{index-ChN9-fAY.js → index-CUM5iXwc.js} +1 -1
  125. package/codeyam-cli/src/webserver/build/client/assets/{index-CcsFv748.js → index-_417gcQW.js} +1 -1
  126. package/codeyam-cli/src/webserver/build/client/assets/labs-DAvt-sy-.js +1 -0
  127. package/codeyam-cli/src/webserver/build/client/assets/{loader-circle-CTqLEAGU.js → loader-circle-TzRHMVog.js} +1 -1
  128. package/codeyam-cli/src/webserver/build/client/assets/manifest-e24d6600.js +1 -0
  129. package/codeyam-cli/src/webserver/build/client/assets/memory-bAp4y2hv.js +92 -0
  130. package/codeyam-cli/src/webserver/build/client/assets/{pause-D6vreykR.js → pause-hjzB7t2z.js} +1 -1
  131. package/codeyam-cli/src/webserver/build/client/assets/root-DoB3B10-.js +62 -0
  132. package/codeyam-cli/src/webserver/build/client/assets/{search-B8VUL8nl.js → search-DcAwD_Ln.js} +1 -1
  133. package/codeyam-cli/src/webserver/build/client/assets/{settings-BejnUJ6R.js → settings-CclxrcPK.js} +1 -1
  134. package/codeyam-cli/src/webserver/build/client/assets/{simulations-CPoAg7Zo.js → simulations-DVNJVQgD.js} +1 -1
  135. package/codeyam-cli/src/webserver/build/client/assets/{terminal-BrCP7uQo.js → terminal-DbEAHMbA.js} +1 -1
  136. package/codeyam-cli/src/webserver/build/client/assets/{triangle-alert-BZz2NjYa.js → triangle-alert-CAD5b1o_.js} +1 -1
  137. package/codeyam-cli/src/webserver/build/client/assets/{useCustomSizes-DNwUduNu.js → useCustomSizes-BqgrAzs3.js} +1 -1
  138. package/codeyam-cli/src/webserver/build/client/assets/{useLastLogLine-COky1GVF.js → useLastLogLine-DAFqfEDH.js} +1 -1
  139. package/codeyam-cli/src/webserver/build/client/assets/{useReportContext-CpZgwliL.js → useReportContext-DZlYx2c4.js} +1 -1
  140. package/codeyam-cli/src/webserver/build/client/assets/{useToast-Bv9JFvUO.js → useToast-ihdMtlf6.js} +1 -1
  141. package/codeyam-cli/src/webserver/build/server/assets/{index-CFKHuovO.js → index-C_nP9_jr.js} +1 -1
  142. package/codeyam-cli/src/webserver/build/server/assets/server-build-BEaMCeTu.js +273 -0
  143. package/codeyam-cli/src/webserver/build/server/index.js +1 -1
  144. package/codeyam-cli/src/webserver/build-info.json +5 -5
  145. package/codeyam-cli/templates/{codeyam:debug.md → codeyam-debug.md} +1 -1
  146. package/codeyam-cli/templates/{codeyam:diagnose.md → codeyam-diagnose.md} +1 -1
  147. package/codeyam-cli/templates/{codeyam:memory.md → codeyam-memory.md} +7 -3
  148. package/codeyam-cli/templates/{codeyam:new-rule.md → codeyam-new-rule.md} +1 -1
  149. package/codeyam-cli/templates/{codeyam:setup.md → codeyam-setup.md} +1 -1
  150. package/codeyam-cli/templates/{codeyam:sim.md → codeyam-sim.md} +1 -1
  151. package/codeyam-cli/templates/{codeyam:test.md → codeyam-test.md} +1 -1
  152. package/codeyam-cli/templates/{codeyam:verify.md → codeyam-verify.md} +1 -1
  153. package/codeyam-cli/templates/rule-reflection-hook.py +1 -1
  154. package/codeyam-cli/templates/rules-instructions.md +1 -1
  155. package/package.json +12 -12
  156. package/packages/ai/index.js +1 -1
  157. package/packages/ai/index.js.map +1 -1
  158. package/packages/ai/src/lib/analyzeScope.js +14 -0
  159. package/packages/ai/src/lib/analyzeScope.js.map +1 -1
  160. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js +213 -3
  161. package/packages/ai/src/lib/dataStructure/ScopeDataStructure.js.map +1 -1
  162. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js +24 -16
  163. package/packages/ai/src/lib/dataStructure/helpers/convertDotNotation.js.map +1 -1
  164. package/packages/ai/src/lib/dataStructureChunking.js +9 -5
  165. package/packages/ai/src/lib/dataStructureChunking.js.map +1 -1
  166. package/packages/ai/src/lib/generateExecutionFlows.js +81 -0
  167. package/packages/ai/src/lib/generateExecutionFlows.js.map +1 -1
  168. package/packages/analyze/src/lib/asts/nodes/getNodeType.js +1 -0
  169. package/packages/analyze/src/lib/asts/nodes/getNodeType.js.map +1 -1
  170. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js +11 -1
  171. package/packages/analyze/src/lib/files/analyze/analyzeEntities/prepareDataStructures.js.map +1 -1
  172. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js +42 -13
  173. package/packages/analyze/src/lib/files/scenarios/gatherDataForMocks.js.map +1 -1
  174. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js +123 -67
  175. package/packages/analyze/src/lib/files/scenarios/mergeInDependentDataStructure.js.map +1 -1
  176. package/packages/utils/src/lib/fs/rsyncCopy.js +98 -3
  177. package/packages/utils/src/lib/fs/rsyncCopy.js.map +1 -1
  178. package/codeyam-cli/src/webserver/build/client/assets/agent-transcripts-CN61MOMa.js +0 -11
  179. package/codeyam-cli/src/webserver/build/client/assets/api.labs-survey-l0sNRNKZ.js +0 -1
  180. package/codeyam-cli/src/webserver/build/client/assets/globals-CuCsBc3b.css +0 -1
  181. package/codeyam-cli/src/webserver/build/client/assets/labs-CB3MGcys.js +0 -1
  182. package/codeyam-cli/src/webserver/build/client/assets/manifest-de6ccaf4.js +0 -1
  183. package/codeyam-cli/src/webserver/build/client/assets/memory-DCA-kLYt.js +0 -81
  184. package/codeyam-cli/src/webserver/build/client/assets/root-F7e6dvys.js +0 -62
  185. package/codeyam-cli/src/webserver/build/server/assets/server-build-BQe9Dh4p.js +0 -260
@@ -0,0 +1,83 @@
1
+ import { parseFrontmatter } from "../parser.js";
2
+ describe('parseFrontmatter', () => {
3
+ it('parses multi-line paths array', () => {
4
+ const content = `---
5
+ paths:
6
+ - 'apps/web/modules/ee/license-check/**'
7
+ - 'apps/web/modules/ee/license-check/**/*.ts'
8
+ ---
9
+
10
+ ## License System
11
+ `;
12
+ const { frontmatter, body } = parseFrontmatter(content);
13
+ expect(frontmatter.paths).toEqual([
14
+ 'apps/web/modules/ee/license-check/**',
15
+ 'apps/web/modules/ee/license-check/**/*.ts',
16
+ ]);
17
+ expect(body.trim()).toBe('## License System');
18
+ });
19
+ it('parses inline YAML array with single-quoted strings', () => {
20
+ const content = `---
21
+ paths: ['apps/web/modules/ee/license-check/**']
22
+ ---
23
+
24
+ ## License System
25
+ `;
26
+ const { frontmatter } = parseFrontmatter(content);
27
+ expect(frontmatter.paths).toEqual(['apps/web/modules/ee/license-check/**']);
28
+ });
29
+ it('parses inline YAML array with double-quoted strings', () => {
30
+ const content = `---
31
+ paths: ["apps/web/modules/ee/license-check/**", "apps/web/lib/**"]
32
+ ---
33
+
34
+ ## Content
35
+ `;
36
+ const { frontmatter } = parseFrontmatter(content);
37
+ expect(frontmatter.paths).toEqual([
38
+ 'apps/web/modules/ee/license-check/**',
39
+ 'apps/web/lib/**',
40
+ ]);
41
+ });
42
+ it('parses inline YAML array without quotes', () => {
43
+ const content = `---
44
+ paths: [apps/web/modules/ee/license-check/**]
45
+ ---
46
+
47
+ ## Content
48
+ `;
49
+ const { frontmatter } = parseFrontmatter(content);
50
+ expect(frontmatter.paths).toEqual(['apps/web/modules/ee/license-check/**']);
51
+ });
52
+ it('parses paths without quotes in multi-line format', () => {
53
+ const content = `---
54
+ paths:
55
+ - apps/web/modules/ee/license-check/**
56
+ ---
57
+
58
+ ## Content
59
+ `;
60
+ const { frontmatter } = parseFrontmatter(content);
61
+ expect(frontmatter.paths).toEqual(['apps/web/modules/ee/license-check/**']);
62
+ });
63
+ it('returns empty frontmatter when no frontmatter present', () => {
64
+ const content = '## Just Content\n\nNo frontmatter here.';
65
+ const { frontmatter, body } = parseFrontmatter(content);
66
+ expect(frontmatter).toEqual({});
67
+ expect(body).toBe(content);
68
+ });
69
+ it('parses category field', () => {
70
+ const content = `---
71
+ paths:
72
+ - 'src/**'
73
+ category: architecture
74
+ ---
75
+
76
+ ## Architecture
77
+ `;
78
+ const { frontmatter } = parseFrontmatter(content);
79
+ expect(frontmatter.paths).toEqual(['src/**']);
80
+ expect(frontmatter.category).toBe('architecture');
81
+ });
82
+ });
83
+ //# sourceMappingURL=parser.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.test.js","sourceRoot":"","sources":["../../../../../../src/utils/rules/__tests__/parser.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7C,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,OAAO,GAAG;;;;;;;CAOnB,CAAC;QACE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;YAChC,sCAAsC;YACtC,2CAA2C;SAC5C,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,OAAO,GAAG;;;;;CAKnB,CAAC;QACE,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,OAAO,GAAG;;;;;CAKnB,CAAC;QACE,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;YAChC,sCAAsC;YACtC,iBAAiB;SAClB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,OAAO,GAAG;;;;;CAKnB,CAAC;QACE,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,OAAO,GAAG;;;;;;CAMnB,CAAC;QACE,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,OAAO,GAAG,yCAAyC,CAAC;QAC1D,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACxD,MAAM,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,OAAO,GAAG;;;;;;;CAOnB,CAAC;QACE,MAAM,EAAE,WAAW,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC9C,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,118 @@
1
+ import { doesPathMatchRule, getRulesForPath, getSourceFilesForRule, } from "../pathMatcher.js";
2
+ function makeRule(filePath, paths) {
3
+ return {
4
+ filePath,
5
+ absolutePath: `/project/.claude/rules/${filePath}`,
6
+ frontmatter: { paths },
7
+ body: 'rule content',
8
+ };
9
+ }
10
+ describe('doesPathMatchRule', () => {
11
+ it('returns false when rule has no paths', () => {
12
+ const rule = makeRule('general.md');
13
+ expect(doesPathMatchRule('src/index.ts', rule)).toBe(false);
14
+ });
15
+ it('returns false when rule has empty paths array', () => {
16
+ const rule = makeRule('general.md', []);
17
+ expect(doesPathMatchRule('src/index.ts', rule)).toBe(false);
18
+ });
19
+ it('matches glob patterns', () => {
20
+ const rule = makeRule('ts-rules.md', ['**/*.ts']);
21
+ expect(doesPathMatchRule('src/index.ts', rule)).toBe(true);
22
+ expect(doesPathMatchRule('src/App.tsx', rule)).toBe(false);
23
+ });
24
+ it('matches with matchBase option', () => {
25
+ const rule = makeRule('component-rules.md', ['*.tsx']);
26
+ expect(doesPathMatchRule('src/components/Button.tsx', rule)).toBe(true);
27
+ });
28
+ });
29
+ describe('getRulesForPath', () => {
30
+ it('returns all matching rules for a path', () => {
31
+ const rules = [
32
+ makeRule('ts.md', ['**/*.ts']),
33
+ makeRule('tsx.md', ['**/*.tsx']),
34
+ makeRule('all-src.md', ['src/**']),
35
+ ];
36
+ const matches = getRulesForPath('src/index.ts', rules);
37
+ expect(matches.map((r) => r.filePath)).toEqual(['ts.md', 'all-src.md']);
38
+ });
39
+ });
40
+ describe('getSourceFilesForRule', () => {
41
+ const sourceFiles = [
42
+ 'src/index.ts',
43
+ 'src/App.tsx',
44
+ 'src/utils/helpers.ts',
45
+ 'lib/parser.js',
46
+ 'test/setup.ts',
47
+ ];
48
+ it('returns empty array for rule with no paths', () => {
49
+ const rule = makeRule('general.md');
50
+ expect(getSourceFilesForRule(rule, sourceFiles)).toEqual([]);
51
+ });
52
+ it('returns empty array for rule with empty paths array', () => {
53
+ const rule = makeRule('general.md', []);
54
+ expect(getSourceFilesForRule(rule, sourceFiles)).toEqual([]);
55
+ });
56
+ it('returns matching files for glob pattern', () => {
57
+ const rule = makeRule('ts-only.md', ['**/*.ts']);
58
+ const result = getSourceFilesForRule(rule, sourceFiles);
59
+ expect(result.sort()).toEqual([
60
+ 'src/index.ts',
61
+ 'src/utils/helpers.ts',
62
+ 'test/setup.ts',
63
+ ]);
64
+ });
65
+ it('returns matching files for directory pattern', () => {
66
+ const rule = makeRule('src-rules.md', ['src/**']);
67
+ const result = getSourceFilesForRule(rule, sourceFiles);
68
+ expect(result.sort()).toEqual([
69
+ 'src/App.tsx',
70
+ 'src/index.ts',
71
+ 'src/utils/helpers.ts',
72
+ ]);
73
+ });
74
+ it('returns empty array when no files match', () => {
75
+ const rule = makeRule('python.md', ['**/*.py']);
76
+ expect(getSourceFilesForRule(rule, sourceFiles)).toEqual([]);
77
+ });
78
+ it('handles multiple patterns', () => {
79
+ const rule = makeRule('multi.md', ['**/*.tsx', 'lib/**']);
80
+ const result = getSourceFilesForRule(rule, sourceFiles);
81
+ expect(result.sort()).toEqual(['lib/parser.js', 'src/App.tsx']);
82
+ });
83
+ it('uses directory-based matching when rule has no paths and is in a subdirectory', () => {
84
+ const rule = makeRule('src/utils/naming-conventions.md');
85
+ const result = getSourceFilesForRule(rule, sourceFiles);
86
+ expect(result).toEqual(['src/utils/helpers.ts']);
87
+ });
88
+ it('does not use directory-based matching for root-level rules with no paths', () => {
89
+ const rule = makeRule('general.md');
90
+ expect(getSourceFilesForRule(rule, sourceFiles)).toEqual([]);
91
+ });
92
+ });
93
+ describe('doesPathMatchRule - directory-based matching', () => {
94
+ it('matches files in the same directory as the rule when no paths specified', () => {
95
+ const rule = makeRule('apps/web/modules/survey/editor/survey-editor-gotchas.md');
96
+ expect(doesPathMatchRule('apps/web/modules/survey/editor/SurveyEditor.tsx', rule)).toBe(true);
97
+ });
98
+ it('matches files in subdirectories of the rule directory', () => {
99
+ const rule = makeRule('apps/web/modules/survey/editor/survey-editor-gotchas.md');
100
+ expect(doesPathMatchRule('apps/web/modules/survey/editor/components/QuestionList.tsx', rule)).toBe(true);
101
+ });
102
+ it('does not match files outside the rule directory', () => {
103
+ const rule = makeRule('apps/web/modules/survey/editor/survey-editor-gotchas.md');
104
+ expect(doesPathMatchRule('apps/web/modules/survey/SurveyList.tsx', rule)).toBe(false);
105
+ });
106
+ it('does not use directory-based matching for root-level rules', () => {
107
+ const rule = makeRule('general-guidelines.md');
108
+ expect(doesPathMatchRule('src/index.ts', rule)).toBe(false);
109
+ });
110
+ it('explicit paths take precedence over directory-based matching', () => {
111
+ const rule = makeRule('src/utils/naming.md', ['**/*.tsx']);
112
+ // Should match based on explicit paths, not directory
113
+ expect(doesPathMatchRule('lib/Component.tsx', rule)).toBe(true);
114
+ // Should NOT match .ts files even though they are in src/utils/
115
+ expect(doesPathMatchRule('src/utils/helpers.ts', rule)).toBe(false);
116
+ });
117
+ });
118
+ //# sourceMappingURL=pathMatcher.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pathMatcher.test.js","sourceRoot":"","sources":["../../../../../../src/utils/rules/__tests__/pathMatcher.test.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AAGxB,SAAS,QAAQ,CAAC,QAAgB,EAAE,KAAgB;IAClD,OAAO;QACL,QAAQ;QACR,YAAY,EAAE,0BAA0B,QAAQ,EAAE;QAClD,WAAW,EAAE,EAAE,KAAK,EAAE;QACtB,IAAI,EAAE,cAAc;KACrB,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QACpC,MAAM,CAAC,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;QAC/B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAClD,MAAM,CAAC,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,MAAM,CAAC,iBAAiB,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,oBAAoB,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,iBAAiB,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,KAAK,GAAG;YACZ,QAAQ,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;YAC9B,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,CAAC;YAChC,QAAQ,CAAC,YAAY,EAAE,CAAC,QAAQ,CAAC,CAAC;SACnC,CAAC;QAEF,MAAM,OAAO,GAAG,eAAe,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,MAAM,WAAW,GAAG;QAClB,cAAc;QACd,aAAa;QACb,sBAAsB;QACtB,eAAe;QACf,eAAe;KAChB,CAAC;IAEF,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QACpC,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACxC,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC;YAC5B,cAAc;YACd,sBAAsB;YACtB,eAAe;SAChB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC;YAC5B,aAAa;YACb,cAAc;YACd,sBAAsB;SACvB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;QAChD,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC1D,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,MAAM,IAAI,GAAG,QAAQ,CAAC,iCAAiC,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,MAAM,IAAI,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;QACpC,MAAM,CAAC,qBAAqB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8CAA8C,EAAE,GAAG,EAAE;IAC5D,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,IAAI,GAAG,QAAQ,CACnB,yDAAyD,CAC1D,CAAC;QACF,MAAM,CACJ,iBAAiB,CACf,iDAAiD,EACjD,IAAI,CACL,CACF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,IAAI,GAAG,QAAQ,CACnB,yDAAyD,CAC1D,CAAC;QACF,MAAM,CACJ,iBAAiB,CACf,4DAA4D,EAC5D,IAAI,CACL,CACF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,IAAI,GAAG,QAAQ,CACnB,yDAAyD,CAC1D,CAAC;QACF,MAAM,CACJ,iBAAiB,CAAC,wCAAwC,EAAE,IAAI,CAAC,CAClE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACpE,MAAM,IAAI,GAAG,QAAQ,CAAC,uBAAuB,CAAC,CAAC;QAC/C,MAAM,CAAC,iBAAiB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,IAAI,GAAG,QAAQ,CAAC,qBAAqB,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;QAC3D,sDAAsD;QACtD,MAAM,CAAC,iBAAiB,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,gEAAgE;QAChE,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,83 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as os from 'os';
4
+ import { findSourceFilesInProject } from "../sourceFiles.js";
5
+ describe('findSourceFilesInProject', () => {
6
+ let tempDir;
7
+ beforeEach(() => {
8
+ tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'codeyam-sourcefiles-'));
9
+ });
10
+ afterEach(() => {
11
+ fs.rmSync(tempDir, { recursive: true, force: true });
12
+ });
13
+ it('returns source files with correct relative paths', () => {
14
+ fs.mkdirSync(path.join(tempDir, 'src'), { recursive: true });
15
+ fs.writeFileSync(path.join(tempDir, 'src', 'index.ts'), '');
16
+ fs.writeFileSync(path.join(tempDir, 'src', 'App.tsx'), '');
17
+ return findSourceFilesInProject(tempDir).then((files) => {
18
+ expect(files.sort()).toEqual(['src/App.tsx', 'src/index.ts']);
19
+ });
20
+ });
21
+ it('finds files with all supported extensions', () => {
22
+ fs.writeFileSync(path.join(tempDir, 'a.ts'), '');
23
+ fs.writeFileSync(path.join(tempDir, 'b.tsx'), '');
24
+ fs.writeFileSync(path.join(tempDir, 'c.js'), '');
25
+ fs.writeFileSync(path.join(tempDir, 'd.jsx'), '');
26
+ fs.writeFileSync(path.join(tempDir, 'e.vue'), '');
27
+ fs.writeFileSync(path.join(tempDir, 'f.svelte'), '');
28
+ return findSourceFilesInProject(tempDir).then((files) => {
29
+ expect(files.sort()).toEqual([
30
+ 'a.ts',
31
+ 'b.tsx',
32
+ 'c.js',
33
+ 'd.jsx',
34
+ 'e.vue',
35
+ 'f.svelte',
36
+ ]);
37
+ });
38
+ });
39
+ it('excludes non-source extensions', () => {
40
+ fs.writeFileSync(path.join(tempDir, 'readme.md'), '');
41
+ fs.writeFileSync(path.join(tempDir, 'style.css'), '');
42
+ fs.writeFileSync(path.join(tempDir, 'data.json'), '');
43
+ fs.writeFileSync(path.join(tempDir, 'real.ts'), '');
44
+ return findSourceFilesInProject(tempDir).then((files) => {
45
+ expect(files).toEqual(['real.ts']);
46
+ });
47
+ });
48
+ it('skips excluded directories', () => {
49
+ const excludedDirs = [
50
+ 'node_modules',
51
+ '.git',
52
+ 'dist',
53
+ '.codeyam',
54
+ '.claude',
55
+ 'build',
56
+ 'coverage',
57
+ ];
58
+ for (const dir of excludedDirs) {
59
+ fs.mkdirSync(path.join(tempDir, dir), { recursive: true });
60
+ fs.writeFileSync(path.join(tempDir, dir, 'file.ts'), '');
61
+ }
62
+ fs.mkdirSync(path.join(tempDir, 'src'), { recursive: true });
63
+ fs.writeFileSync(path.join(tempDir, 'src', 'real.ts'), '');
64
+ return findSourceFilesInProject(tempDir).then((files) => {
65
+ expect(files).toEqual(['src/real.ts']);
66
+ });
67
+ });
68
+ it('returns empty array for projects with no source files', () => {
69
+ return findSourceFilesInProject(tempDir).then((files) => {
70
+ expect(files).toEqual([]);
71
+ });
72
+ });
73
+ it('recurses into nested directories', () => {
74
+ fs.mkdirSync(path.join(tempDir, 'src', 'components', 'ui'), {
75
+ recursive: true,
76
+ });
77
+ fs.writeFileSync(path.join(tempDir, 'src', 'components', 'ui', 'Button.tsx'), '');
78
+ return findSourceFilesInProject(tempDir).then((files) => {
79
+ expect(files).toEqual(['src/components/ui/Button.tsx']);
80
+ });
81
+ });
82
+ });
83
+ //# sourceMappingURL=sourceFiles.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceFiles.test.js","sourceRoot":"","sources":["../../../../../../src/utils/rules/__tests__/sourceFiles.test.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  // Re-export all rule utilities
2
2
  export * from "./parser.js";
3
3
  export * from "./pathMatcher.js";
4
+ export * from "./sourceFiles.js";
4
5
  export * from "./staleness.js";
5
6
  export * from "./ruleState.js";
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/utils/rules/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/utils/rules/index.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
@@ -14,10 +14,14 @@ export function parseFrontmatter(content) {
14
14
  const body = match[2];
15
15
  // Simple YAML parser for our specific format
16
16
  const frontmatter = {};
17
- // Parse paths array
18
- const pathsMatch = yamlContent.match(/paths:\s*\n((?:\s+-\s+[^\n]+\n?)*)/);
19
- if (pathsMatch) {
20
- frontmatter.paths = pathsMatch[1]
17
+ // Parse paths array - supports both multi-line and inline YAML formats:
18
+ // paths: paths: ['src/**', 'lib/**']
19
+ // - 'src/**' paths: [src/**]
20
+ // - 'lib/**'
21
+ const multiLineMatch = yamlContent.match(/paths:\s*\n((?:\s+-\s+[^\n]+\n?)*)/);
22
+ const inlineMatch = yamlContent.match(/paths:\s*\[([^\]]*)\]/);
23
+ if (multiLineMatch && multiLineMatch[1].trim()) {
24
+ frontmatter.paths = multiLineMatch[1]
21
25
  .split('\n')
22
26
  .filter((line) => line.trim().startsWith('-'))
23
27
  .map((line) => line
@@ -26,6 +30,12 @@ export function parseFrontmatter(content) {
26
30
  .trim())
27
31
  .filter(Boolean);
28
32
  }
33
+ else if (inlineMatch) {
34
+ frontmatter.paths = inlineMatch[1]
35
+ .split(',')
36
+ .map((item) => item.replace(/['"]/g, '').trim())
37
+ .filter(Boolean);
38
+ }
29
39
  // Parse category
30
40
  const categoryMatch = yamlContent.match(/^category:\s*(.+)$/m);
31
41
  if (categoryMatch) {
@@ -1 +1 @@
1
- {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../../src/utils/rules/parser.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,aAAa,CAAC;AAc7B;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAI9C,MAAM,gBAAgB,GAAG,oCAAoC,CAAC;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAE9C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IAEtB,6CAA6C;IAC7C,MAAM,WAAW,GAAoB,EAAE,CAAC;IAExC,oBAAoB;IACpB,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC3E,IAAI,UAAU,EAAE,CAAC;QACf,WAAW,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC;aAC9B,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;aAC7C,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,IAAI;aACD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;aACvB,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;aACpB,IAAI,EAAE,CACV;aACA,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,iBAAiB;IACjB,MAAM,aAAa,GAAG,WAAW,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC/D,IAAI,aAAa,EAAE,CAAC;QAClB,WAAW,CAAC,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtE,CAAC;IAED,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,QAAQ,GAAG,EAAE;IAEb,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;YAEzE,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,MAAM,UAAU,GAAG,MAAM,iBAAiB,CACxC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAC1B,YAAY,CACb,CAAC;gBACF,OAAO,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;YAC9B,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0CAA0C;IAC5C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,KAAK,GAAW,EAAE,CAAC;IAEzB,KAAK,MAAM,YAAY,IAAI,KAAK,EAAE,CAAC;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;YACzD,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAExD,KAAK,CAAC,IAAI,CAAC;gBACT,QAAQ,EAAE,YAAY;gBACtB,YAAY;gBACZ,WAAW;gBACX,IAAI;aACL,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../../../src/utils/rules/parser.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,33 @@
1
1
  // Path matching utilities for Claude Rules
2
2
  import { minimatch } from 'minimatch';
3
+ import path from 'path';
4
+ /**
5
+ * Derive the implicit directory pattern from a rule's location within .claude/rules/.
6
+ * In Claude Code, rules placed in subdirectories automatically apply to files
7
+ * in the corresponding project directory (e.g., .claude/rules/src/utils/foo.md
8
+ * applies to files under src/utils/).
9
+ * Returns null for root-level rules (no directory component).
10
+ */
11
+ function getImplicitDirectoryPattern(rule) {
12
+ const dir = path.posix.dirname(rule.filePath);
13
+ if (!dir || dir === '.') {
14
+ return null;
15
+ }
16
+ return `${dir}/**`;
17
+ }
3
18
  /**
4
19
  * Check if a file path matches any of a rule's path patterns
5
20
  */
6
21
  export function doesPathMatchRule(filePath, rule) {
7
- if (!rule.frontmatter.paths || rule.frontmatter.paths.length === 0) {
8
- return false;
22
+ if (rule.frontmatter.paths && rule.frontmatter.paths.length > 0) {
23
+ return rule.frontmatter.paths.some((pattern) => minimatch(filePath, pattern, { matchBase: true }));
24
+ }
25
+ // Fall back to directory-based matching for rules in subdirectories
26
+ const implicitPattern = getImplicitDirectoryPattern(rule);
27
+ if (implicitPattern) {
28
+ return minimatch(filePath, implicitPattern, { matchBase: true });
9
29
  }
10
- return rule.frontmatter.paths.some((pattern) => minimatch(filePath, pattern, { matchBase: true }));
30
+ return false;
11
31
  }
12
32
  /**
13
33
  * Find all rules that match a given file path
@@ -15,4 +35,15 @@ export function doesPathMatchRule(filePath, rule) {
15
35
  export function getRulesForPath(filePath, rules) {
16
36
  return rules.filter((rule) => doesPathMatchRule(filePath, rule));
17
37
  }
38
+ /**
39
+ * Find all source files that match a given rule's path patterns.
40
+ * Inverse of getRulesForPath.
41
+ */
42
+ export function getSourceFilesForRule(rule, sourceFiles) {
43
+ if ((!rule.frontmatter.paths || rule.frontmatter.paths.length === 0) &&
44
+ !getImplicitDirectoryPattern(rule)) {
45
+ return [];
46
+ }
47
+ return sourceFiles.filter((filePath) => doesPathMatchRule(filePath, rule));
48
+ }
18
49
  //# sourceMappingURL=pathMatcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pathMatcher.js","sourceRoot":"","sources":["../../../../../src/utils/rules/pathMatcher.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,IAAU;IAC5D,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnE,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7C,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAClD,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,KAAa;IAC7D,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"pathMatcher.js","sourceRoot":"","sources":["../../../../../src/utils/rules/pathMatcher.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB;;;;;;GAMG;AACH,SAAS,2BAA2B,CAAC,IAAU;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9C,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,GAAG,GAAG,KAAK,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,IAAU;IAC5D,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7C,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAClD,CAAC;IACJ,CAAC;IAED,oEAAoE;IACpE,MAAM,eAAe,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAC;IAC1D,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,SAAS,CAAC,QAAQ,EAAE,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,KAAa;IAC7D,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAU,EACV,WAAqB;IAErB,IACE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC;QAChE,CAAC,2BAA2B,CAAC,IAAI,CAAC,EAClC,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,47 @@
1
+ import * as fs from 'fs/promises';
2
+ import * as path from 'path';
3
+ const SOURCE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte'];
4
+ const EXCLUDED_DIRS = new Set([
5
+ 'node_modules',
6
+ '.git',
7
+ 'dist',
8
+ '.codeyam',
9
+ '.claude',
10
+ 'build',
11
+ 'coverage',
12
+ ]);
13
+ /**
14
+ * Find all source files in a project, returning paths relative to projectRoot.
15
+ */
16
+ export async function findSourceFilesInProject(projectRoot) {
17
+ const sourceFiles = [];
18
+ async function walkDir(dir, relativePath) {
19
+ try {
20
+ const entries = await fs.readdir(dir, { withFileTypes: true });
21
+ for (const entry of entries) {
22
+ const fullPath = path.join(dir, entry.name);
23
+ const relPath = relativePath
24
+ ? `${relativePath}/${entry.name}`
25
+ : entry.name;
26
+ if (entry.isDirectory() && EXCLUDED_DIRS.has(entry.name)) {
27
+ continue;
28
+ }
29
+ if (entry.isDirectory()) {
30
+ await walkDir(fullPath, relPath);
31
+ }
32
+ else if (entry.isFile()) {
33
+ const ext = path.extname(entry.name);
34
+ if (SOURCE_EXTENSIONS.includes(ext)) {
35
+ sourceFiles.push(relPath);
36
+ }
37
+ }
38
+ }
39
+ }
40
+ catch {
41
+ // Directory not readable, skip
42
+ }
43
+ }
44
+ await walkDir(projectRoot, '');
45
+ return sourceFiles;
46
+ }
47
+ //# sourceMappingURL=sourceFiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceFiles.js","sourceRoot":"","sources":["../../../../../src/utils/rules/sourceFiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;AAE5E,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC;IAC5B,cAAc;IACd,MAAM;IACN,MAAM;IACN,UAAU;IACV,SAAS;IACT,OAAO;IACP,UAAU;CACX,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,WAAmB;IAEnB,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,YAAoB;QACtD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC5C,MAAM,OAAO,GAAG,YAAY;oBAC1B,CAAC,CAAC,GAAG,YAAY,IAAI,KAAK,CAAC,IAAI,EAAE;oBACjC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;gBAEf,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzD,SAAS;gBACX,CAAC;gBAED,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;oBACxB,MAAM,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACnC,CAAC;qBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;oBAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACrC,IAAI,iBAAiB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBACpC,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,+BAA+B;QACjC,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC/B,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -39,8 +39,8 @@ export function setupClaudeCodeSettings(projectRoot, options) {
39
39
  }
40
40
  // Memory permissions — always included
41
41
  const memoryPermissions = [
42
- 'Skill(codeyam:memory)',
43
- 'Skill(codeyam:new-rule)',
42
+ 'Skill(codeyam-memory)',
43
+ 'Skill(codeyam-new-rule)',
44
44
  'Bash(codeyam)',
45
45
  'Bash(codeyam:*)',
46
46
  'Read(.codeyam/**)',
@@ -50,11 +50,11 @@ export function setupClaudeCodeSettings(projectRoot, options) {
50
50
  ];
51
51
  // Simulation permissions — only in full mode
52
52
  const simulationPermissions = [
53
- 'Skill(codeyam:setup)',
54
- 'Skill(codeyam:sim)',
55
- 'Skill(codeyam:debug)',
56
- 'Skill(codeyam:test)',
57
- 'Skill(codeyam:verify)',
53
+ 'Skill(codeyam-setup)',
54
+ 'Skill(codeyam-sim)',
55
+ 'Skill(codeyam-debug)',
56
+ 'Skill(codeyam-test)',
57
+ 'Skill(codeyam-verify)',
58
58
  'Read(/tmp/codeyam/**)',
59
59
  'Edit(/tmp/codeyam/**)',
60
60
  'Write(/tmp/codeyam/**)',