@mcoda/core 0.1.8 → 0.1.11

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 (216) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/README.md +2 -2
  3. package/dist/api/AgentsApi.d.ts +9 -1
  4. package/dist/api/AgentsApi.d.ts.map +1 -1
  5. package/dist/api/AgentsApi.js +201 -6
  6. package/dist/api/QaTasksApi.d.ts.map +1 -1
  7. package/dist/api/QaTasksApi.js +6 -0
  8. package/dist/api/TasksApi.d.ts.map +1 -1
  9. package/dist/api/TasksApi.js +1 -0
  10. package/dist/index.d.ts +4 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +4 -0
  13. package/dist/prompts/PdrPrompts.d.ts.map +1 -1
  14. package/dist/prompts/PdrPrompts.js +9 -1
  15. package/dist/prompts/SdsPrompts.d.ts.map +1 -1
  16. package/dist/prompts/SdsPrompts.js +9 -0
  17. package/dist/services/agents/AgentRatingFormula.d.ts +27 -0
  18. package/dist/services/agents/AgentRatingFormula.d.ts.map +1 -0
  19. package/dist/services/agents/AgentRatingFormula.js +45 -0
  20. package/dist/services/agents/AgentRatingService.d.ts +60 -0
  21. package/dist/services/agents/AgentRatingService.d.ts.map +1 -0
  22. package/dist/services/agents/AgentRatingService.js +363 -0
  23. package/dist/services/agents/GatewayAgentService.d.ts +11 -0
  24. package/dist/services/agents/GatewayAgentService.d.ts.map +1 -1
  25. package/dist/services/agents/GatewayAgentService.js +525 -84
  26. package/dist/services/agents/GatewayHandoff.d.ts +11 -0
  27. package/dist/services/agents/GatewayHandoff.d.ts.map +1 -0
  28. package/dist/services/agents/GatewayHandoff.js +141 -0
  29. package/dist/services/agents/RoutingService.d.ts +1 -0
  30. package/dist/services/agents/RoutingService.d.ts.map +1 -1
  31. package/dist/services/agents/RoutingService.js +4 -4
  32. package/dist/services/backlog/BacklogService.d.ts +23 -0
  33. package/dist/services/backlog/BacklogService.d.ts.map +1 -1
  34. package/dist/services/backlog/BacklogService.js +62 -7
  35. package/dist/services/backlog/TaskOrderingHeuristics.d.ts +12 -0
  36. package/dist/services/backlog/TaskOrderingHeuristics.d.ts.map +1 -0
  37. package/dist/services/backlog/TaskOrderingHeuristics.js +56 -0
  38. package/dist/services/backlog/TaskOrderingService.d.ts +17 -4
  39. package/dist/services/backlog/TaskOrderingService.d.ts.map +1 -1
  40. package/dist/services/backlog/TaskOrderingService.js +538 -79
  41. package/dist/services/docs/DocInventory.d.ts +11 -0
  42. package/dist/services/docs/DocInventory.d.ts.map +1 -0
  43. package/dist/services/docs/DocInventory.js +230 -0
  44. package/dist/services/docs/DocgenRunContext.d.ts +59 -0
  45. package/dist/services/docs/DocgenRunContext.d.ts.map +1 -0
  46. package/dist/services/docs/DocgenRunContext.js +4 -0
  47. package/dist/services/docs/DocsService.d.ts +70 -3
  48. package/dist/services/docs/DocsService.d.ts.map +1 -1
  49. package/dist/services/docs/DocsService.js +1930 -89
  50. package/dist/services/docs/alignment/DocAlignmentGraph.d.ts +23 -0
  51. package/dist/services/docs/alignment/DocAlignmentGraph.d.ts.map +1 -0
  52. package/dist/services/docs/alignment/DocAlignmentGraph.js +78 -0
  53. package/dist/services/docs/alignment/DocAlignmentPatcher.d.ts +19 -0
  54. package/dist/services/docs/alignment/DocAlignmentPatcher.d.ts.map +1 -0
  55. package/dist/services/docs/alignment/DocAlignmentPatcher.js +222 -0
  56. package/dist/services/docs/patch/DocPatchEngine.d.ts +57 -0
  57. package/dist/services/docs/patch/DocPatchEngine.d.ts.map +1 -0
  58. package/dist/services/docs/patch/DocPatchEngine.js +331 -0
  59. package/dist/services/docs/review/Glossary.d.ts +16 -0
  60. package/dist/services/docs/review/Glossary.d.ts.map +1 -0
  61. package/dist/services/docs/review/Glossary.js +47 -0
  62. package/dist/services/docs/review/ReviewReportRenderer.d.ts +3 -0
  63. package/dist/services/docs/review/ReviewReportRenderer.d.ts.map +1 -0
  64. package/dist/services/docs/review/ReviewReportRenderer.js +133 -0
  65. package/dist/services/docs/review/ReviewReportSchema.d.ts +39 -0
  66. package/dist/services/docs/review/ReviewReportSchema.d.ts.map +1 -0
  67. package/dist/services/docs/review/ReviewReportSchema.js +47 -0
  68. package/dist/services/docs/review/ReviewTypes.d.ts +76 -0
  69. package/dist/services/docs/review/ReviewTypes.d.ts.map +1 -0
  70. package/dist/services/docs/review/ReviewTypes.js +94 -0
  71. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.d.ts +7 -0
  72. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.d.ts.map +1 -0
  73. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.js +93 -0
  74. package/dist/services/docs/review/gates/ApiPathConsistencyGate.d.ts +7 -0
  75. package/dist/services/docs/review/gates/ApiPathConsistencyGate.d.ts.map +1 -0
  76. package/dist/services/docs/review/gates/ApiPathConsistencyGate.js +308 -0
  77. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.d.ts +8 -0
  78. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.d.ts.map +1 -0
  79. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.js +278 -0
  80. package/dist/services/docs/review/gates/DeploymentBlueprintGate.d.ts +8 -0
  81. package/dist/services/docs/review/gates/DeploymentBlueprintGate.d.ts.map +1 -0
  82. package/dist/services/docs/review/gates/DeploymentBlueprintGate.js +487 -0
  83. package/dist/services/docs/review/gates/NoMaybesGate.d.ts +8 -0
  84. package/dist/services/docs/review/gates/NoMaybesGate.d.ts.map +1 -0
  85. package/dist/services/docs/review/gates/NoMaybesGate.js +145 -0
  86. package/dist/services/docs/review/gates/OpenApiCoverageGate.d.ts +7 -0
  87. package/dist/services/docs/review/gates/OpenApiCoverageGate.d.ts.map +1 -0
  88. package/dist/services/docs/review/gates/OpenApiCoverageGate.js +266 -0
  89. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.d.ts +7 -0
  90. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.d.ts.map +1 -0
  91. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.js +59 -0
  92. package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts +7 -0
  93. package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts.map +1 -0
  94. package/dist/services/docs/review/gates/OpenQuestionsGate.js +200 -0
  95. package/dist/services/docs/review/gates/PdrInterfacesGate.d.ts +7 -0
  96. package/dist/services/docs/review/gates/PdrInterfacesGate.d.ts.map +1 -0
  97. package/dist/services/docs/review/gates/PdrInterfacesGate.js +159 -0
  98. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.d.ts +8 -0
  99. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.d.ts.map +1 -0
  100. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.js +129 -0
  101. package/dist/services/docs/review/gates/PdrOwnershipGate.d.ts +7 -0
  102. package/dist/services/docs/review/gates/PdrOwnershipGate.d.ts.map +1 -0
  103. package/dist/services/docs/review/gates/PdrOwnershipGate.js +169 -0
  104. package/dist/services/docs/review/gates/PlaceholderArtifactGate.d.ts +10 -0
  105. package/dist/services/docs/review/gates/PlaceholderArtifactGate.d.ts.map +1 -0
  106. package/dist/services/docs/review/gates/PlaceholderArtifactGate.js +261 -0
  107. package/dist/services/docs/review/gates/RfpConsentGate.d.ts +6 -0
  108. package/dist/services/docs/review/gates/RfpConsentGate.d.ts.map +1 -0
  109. package/dist/services/docs/review/gates/RfpConsentGate.js +127 -0
  110. package/dist/services/docs/review/gates/RfpDefinitionGate.d.ts +7 -0
  111. package/dist/services/docs/review/gates/RfpDefinitionGate.d.ts.map +1 -0
  112. package/dist/services/docs/review/gates/RfpDefinitionGate.js +173 -0
  113. package/dist/services/docs/review/gates/SdsAdaptersGate.d.ts +7 -0
  114. package/dist/services/docs/review/gates/SdsAdaptersGate.d.ts.map +1 -0
  115. package/dist/services/docs/review/gates/SdsAdaptersGate.js +196 -0
  116. package/dist/services/docs/review/gates/SdsDecisionsGate.d.ts +7 -0
  117. package/dist/services/docs/review/gates/SdsDecisionsGate.d.ts.map +1 -0
  118. package/dist/services/docs/review/gates/SdsDecisionsGate.js +89 -0
  119. package/dist/services/docs/review/gates/SdsOpsGate.d.ts +7 -0
  120. package/dist/services/docs/review/gates/SdsOpsGate.d.ts.map +1 -0
  121. package/dist/services/docs/review/gates/SdsOpsGate.js +162 -0
  122. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.d.ts +7 -0
  123. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.d.ts.map +1 -0
  124. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.js +166 -0
  125. package/dist/services/docs/review/gates/SqlRequiredTablesGate.d.ts +7 -0
  126. package/dist/services/docs/review/gates/SqlRequiredTablesGate.d.ts.map +1 -0
  127. package/dist/services/docs/review/gates/SqlRequiredTablesGate.js +273 -0
  128. package/dist/services/docs/review/gates/SqlSyntaxGate.d.ts +7 -0
  129. package/dist/services/docs/review/gates/SqlSyntaxGate.d.ts.map +1 -0
  130. package/dist/services/docs/review/gates/SqlSyntaxGate.js +203 -0
  131. package/dist/services/docs/review/gates/TerminologyNormalizationGate.d.ts +9 -0
  132. package/dist/services/docs/review/gates/TerminologyNormalizationGate.d.ts.map +1 -0
  133. package/dist/services/docs/review/gates/TerminologyNormalizationGate.js +217 -0
  134. package/dist/services/docs/review/glossary.json +47 -0
  135. package/dist/services/estimate/EstimateService.d.ts +2 -0
  136. package/dist/services/estimate/EstimateService.d.ts.map +1 -1
  137. package/dist/services/estimate/EstimateService.js +66 -18
  138. package/dist/services/estimate/VelocityService.d.ts +4 -0
  139. package/dist/services/estimate/VelocityService.d.ts.map +1 -1
  140. package/dist/services/estimate/VelocityService.js +179 -36
  141. package/dist/services/estimate/types.d.ts +1 -0
  142. package/dist/services/estimate/types.d.ts.map +1 -1
  143. package/dist/services/execution/GatewayTrioService.d.ts +200 -0
  144. package/dist/services/execution/GatewayTrioService.d.ts.map +1 -0
  145. package/dist/services/execution/GatewayTrioService.js +2492 -0
  146. package/dist/services/execution/QaApiRunner.d.ts +30 -0
  147. package/dist/services/execution/QaApiRunner.d.ts.map +1 -0
  148. package/dist/services/execution/QaApiRunner.js +881 -0
  149. package/dist/services/execution/QaFollowupService.d.ts +2 -0
  150. package/dist/services/execution/QaFollowupService.d.ts.map +1 -1
  151. package/dist/services/execution/QaFollowupService.js +9 -2
  152. package/dist/services/execution/QaPlanValidator.d.ts +10 -0
  153. package/dist/services/execution/QaPlanValidator.d.ts.map +1 -0
  154. package/dist/services/execution/QaPlanValidator.js +128 -0
  155. package/dist/services/execution/QaProfileService.d.ts +27 -1
  156. package/dist/services/execution/QaProfileService.d.ts.map +1 -1
  157. package/dist/services/execution/QaProfileService.js +354 -7
  158. package/dist/services/execution/QaTasksService.d.ts +59 -1
  159. package/dist/services/execution/QaTasksService.d.ts.map +1 -1
  160. package/dist/services/execution/QaTasksService.js +3347 -318
  161. package/dist/services/execution/QaTestCommandBuilder.d.ts +51 -0
  162. package/dist/services/execution/QaTestCommandBuilder.d.ts.map +1 -0
  163. package/dist/services/execution/QaTestCommandBuilder.js +495 -0
  164. package/dist/services/execution/TaskSelectionService.d.ts +4 -2
  165. package/dist/services/execution/TaskSelectionService.d.ts.map +1 -1
  166. package/dist/services/execution/TaskSelectionService.js +144 -28
  167. package/dist/services/execution/TaskStateService.d.ts +19 -6
  168. package/dist/services/execution/TaskStateService.d.ts.map +1 -1
  169. package/dist/services/execution/TaskStateService.js +128 -13
  170. package/dist/services/execution/WorkOnTasksService.d.ts +32 -1
  171. package/dist/services/execution/WorkOnTasksService.d.ts.map +1 -1
  172. package/dist/services/execution/WorkOnTasksService.js +4667 -722
  173. package/dist/services/jobs/JobInsightsService.d.ts +4 -0
  174. package/dist/services/jobs/JobInsightsService.d.ts.map +1 -1
  175. package/dist/services/jobs/JobInsightsService.js +51 -5
  176. package/dist/services/jobs/JobResumeService.d.ts.map +1 -1
  177. package/dist/services/jobs/JobResumeService.js +23 -10
  178. package/dist/services/jobs/JobService.d.ts +56 -4
  179. package/dist/services/jobs/JobService.d.ts.map +1 -1
  180. package/dist/services/jobs/JobService.js +232 -1
  181. package/dist/services/openapi/OpenApiService.d.ts +51 -0
  182. package/dist/services/openapi/OpenApiService.d.ts.map +1 -1
  183. package/dist/services/openapi/OpenApiService.js +953 -106
  184. package/dist/services/planning/CreateTasksService.d.ts +21 -0
  185. package/dist/services/planning/CreateTasksService.d.ts.map +1 -1
  186. package/dist/services/planning/CreateTasksService.js +569 -31
  187. package/dist/services/planning/RefineTasksService.d.ts +9 -0
  188. package/dist/services/planning/RefineTasksService.d.ts.map +1 -1
  189. package/dist/services/planning/RefineTasksService.js +409 -59
  190. package/dist/services/review/CodeReviewService.d.ts +18 -0
  191. package/dist/services/review/CodeReviewService.d.ts.map +1 -1
  192. package/dist/services/review/CodeReviewService.js +1309 -167
  193. package/dist/services/review/ReviewNormalizer.d.ts +9 -0
  194. package/dist/services/review/ReviewNormalizer.d.ts.map +1 -0
  195. package/dist/services/review/ReviewNormalizer.js +147 -0
  196. package/dist/services/shared/AuthErrors.d.ts +3 -0
  197. package/dist/services/shared/AuthErrors.d.ts.map +1 -0
  198. package/dist/services/shared/AuthErrors.js +17 -0
  199. package/dist/services/shared/DocdexGuidance.d.ts +7 -0
  200. package/dist/services/shared/DocdexGuidance.d.ts.map +1 -0
  201. package/dist/services/shared/DocdexGuidance.js +12 -0
  202. package/dist/services/shared/ProjectGuidance.d.ts +17 -0
  203. package/dist/services/shared/ProjectGuidance.d.ts.map +1 -0
  204. package/dist/services/shared/ProjectGuidance.js +78 -0
  205. package/dist/services/system/ToolDenylist.d.ts +13 -0
  206. package/dist/services/system/ToolDenylist.d.ts.map +1 -0
  207. package/dist/services/system/ToolDenylist.js +85 -0
  208. package/dist/services/tasks/TaskCommentFormatter.d.ts +20 -0
  209. package/dist/services/tasks/TaskCommentFormatter.d.ts.map +1 -0
  210. package/dist/services/tasks/TaskCommentFormatter.js +54 -0
  211. package/dist/services/telemetry/TelemetryService.d.ts.map +1 -1
  212. package/dist/services/telemetry/TelemetryService.js +39 -7
  213. package/dist/workspace/WorkspaceManager.d.ts +26 -0
  214. package/dist/workspace/WorkspaceManager.d.ts.map +1 -1
  215. package/dist/workspace/WorkspaceManager.js +206 -32
  216. package/package.json +6 -5
@@ -1 +1 @@
1
- {"version":3,"file":"WorkspaceManager.d.ts","sourceRoot":"","sources":["../../src/workspace/WorkspaceManager.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE;QACT,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC;AAqHD,qBAAa,iBAAiB;WACf,gBAAgB,CAAC,KAAK,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAiFjH"}
1
+ {"version":3,"file":"WorkspaceManager.d.ts","sourceRoot":"","sources":["../../src/workspace/WorkspaceManager.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,EAAE,CAAC,EAAE;QACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;QAC5B,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,SAAS,CAAC,EAAE,oBAAoB,CAAC;CAClC;AAqDD,eAAO,MAAM,yBAAyB,GAAU,OAAO;IACrD,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,KAAG,OAAO,CAAC,MAAM,EAAE,CAsEnB,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,OAAO;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB,KAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAuB1C,CAAC;AAwIF,qBAAa,iBAAiB;WACf,gBAAgB,CAAC,KAAK,EAAE;QACnC,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAsGjC"}
@@ -1,3 +1,4 @@
1
+ import os from "node:os";
1
2
  import path from "node:path";
2
3
  import { promises as fs } from "node:fs";
3
4
  import { randomUUID } from "node:crypto";
@@ -11,6 +12,138 @@ const fileExists = async (candidate) => {
11
12
  return false;
12
13
  }
13
14
  };
15
+ const dirHasEntries = async (candidate) => {
16
+ try {
17
+ const entries = await fs.readdir(candidate);
18
+ return entries.length > 0;
19
+ }
20
+ catch {
21
+ return false;
22
+ }
23
+ };
24
+ const STATE_DIR_NAMES = [".mcoda", ".mcoda-state", ".mcoda_state"];
25
+ const resolveUniqueTarget = async (base) => {
26
+ if (!(await fileExists(base)))
27
+ return base;
28
+ const parent = path.dirname(base);
29
+ const stem = path.basename(base);
30
+ for (let attempt = 0; attempt < 5; attempt += 1) {
31
+ const candidate = path.join(parent, `${stem}-${randomUUID().slice(0, 8)}`);
32
+ if (!(await fileExists(candidate)))
33
+ return candidate;
34
+ }
35
+ return path.join(parent, `${stem}-${Date.now()}`);
36
+ };
37
+ const copyLegacyConfigIfMissing = async (sourceDir, targetDir, warnings) => {
38
+ const sourceConfig = path.join(sourceDir, "config.json");
39
+ const targetConfig = path.join(targetDir, "config.json");
40
+ if (!(await fileExists(sourceConfig)))
41
+ return;
42
+ if (await fileExists(targetConfig))
43
+ return;
44
+ try {
45
+ await PathHelper.ensureDir(targetDir);
46
+ await fs.copyFile(sourceConfig, targetConfig);
47
+ warnings.push(`Copied legacy workspace config from ${sourceConfig} to ${targetConfig}.`);
48
+ }
49
+ catch (error) {
50
+ warnings.push(`Unable to copy legacy workspace config from ${sourceConfig}: ${error.message ?? String(error)}`);
51
+ }
52
+ };
53
+ export const cleanupWorkspaceStateDirs = async (input) => {
54
+ const warnings = [];
55
+ const workspaceRoot = path.resolve(input.workspaceRoot);
56
+ const mcodaDir = path.resolve(input.mcodaDir);
57
+ for (const name of STATE_DIR_NAMES) {
58
+ const source = path.join(workspaceRoot, name);
59
+ if (!(await fileExists(source)))
60
+ continue;
61
+ if (PathHelper.normalizePathCase(source) === PathHelper.normalizePathCase(mcodaDir)) {
62
+ continue;
63
+ }
64
+ let stat;
65
+ try {
66
+ stat = await fs.lstat(source);
67
+ }
68
+ catch {
69
+ continue;
70
+ }
71
+ if (stat.isSymbolicLink()) {
72
+ warnings.push(`Skipped legacy state directory symlink at ${source}.`);
73
+ continue;
74
+ }
75
+ if (!stat.isDirectory()) {
76
+ warnings.push(`Skipped legacy state path ${source} because it is not a directory.`);
77
+ continue;
78
+ }
79
+ if (!(await dirHasEntries(source))) {
80
+ try {
81
+ await fs.rm(source, { recursive: true, force: true });
82
+ warnings.push(`Removed empty legacy state directory at ${source}.`);
83
+ }
84
+ catch (error) {
85
+ warnings.push(`Unable to remove empty legacy state directory at ${source}: ${error.message ?? String(error)}`);
86
+ }
87
+ continue;
88
+ }
89
+ if (name === ".mcoda") {
90
+ await copyLegacyConfigIfMissing(source, mcodaDir, warnings);
91
+ }
92
+ const targetName = name.startsWith(".") ? name.slice(1) : name;
93
+ const targetBase = path.join(mcodaDir, "legacy", targetName);
94
+ const target = await resolveUniqueTarget(targetBase);
95
+ await PathHelper.ensureDir(path.dirname(target));
96
+ try {
97
+ await fs.rename(source, target);
98
+ }
99
+ catch (error) {
100
+ const code = error.code;
101
+ if (code === "EXDEV") {
102
+ try {
103
+ await fs.cp(source, target, { recursive: true });
104
+ await fs.rm(source, { recursive: true, force: true });
105
+ }
106
+ catch (copyError) {
107
+ warnings.push(`Unable to relocate legacy state directory from ${source}: ${copyError.message ?? String(copyError)}`);
108
+ continue;
109
+ }
110
+ }
111
+ else {
112
+ warnings.push(`Unable to relocate legacy state directory from ${source}: ${error.message ?? String(error)}`);
113
+ continue;
114
+ }
115
+ }
116
+ warnings.push(`Relocated legacy state directory from ${source} to ${target}.`);
117
+ }
118
+ return warnings;
119
+ };
120
+ export const resolveDocgenStatePath = (input) => {
121
+ const warnings = [];
122
+ const outputPath = path.resolve(input.outputPath);
123
+ const mcodaDir = path.resolve(input.mcodaDir);
124
+ const tempDir = path.resolve(os.tmpdir());
125
+ const allowedRoots = [mcodaDir, tempDir];
126
+ const isAllowed = allowedRoots.some((root) => PathHelper.isPathInside(root, outputPath));
127
+ if (isAllowed) {
128
+ return { statePath: outputPath, warnings };
129
+ }
130
+ const basename = path.basename(outputPath) || "docgen.md";
131
+ const statePath = path.join(mcodaDir, "state", "docgen", input.commandName, input.jobId, basename);
132
+ warnings.push(`Intermediate state redirected from ${outputPath} to ${statePath} to keep docgen state under .mcoda or OS temp directories.`);
133
+ return { statePath, warnings };
134
+ };
135
+ const maybeCopyLegacyWorkspace = async (sourceDir, targetDir) => {
136
+ if (!(await fileExists(sourceDir)))
137
+ return;
138
+ if (await dirHasEntries(targetDir))
139
+ return;
140
+ try {
141
+ await fs.cp(sourceDir, targetDir, { recursive: true });
142
+ }
143
+ catch {
144
+ /* best effort */
145
+ }
146
+ };
14
147
  const findGitRoot = async (start) => {
15
148
  // Only consider the provided directory; do not walk upward.
16
149
  const current = path.resolve(start);
@@ -30,27 +163,34 @@ const findWorkspaceMarker = async (start) => {
30
163
  return current;
31
164
  return undefined;
32
165
  };
33
- const ensureGitignore = async (workspaceRoot) => {
34
- const gitignorePath = path.join(workspaceRoot, ".gitignore");
35
- const entry = ".mcoda/\n";
36
- try {
37
- const content = await fs.readFile(gitignorePath, "utf8");
38
- if (content.includes(".mcoda/"))
39
- return;
40
- await fs.writeFile(gitignorePath, `${content.trimEnd()}\n${entry}`, "utf8");
41
- }
42
- catch {
43
- await fs.writeFile(gitignorePath, entry, "utf8");
166
+ const readWorkspaceConfig = async (mcodaDir, fallbackDir) => {
167
+ const readConfig = async (dir) => {
168
+ const configPath = path.join(dir, "config.json");
169
+ try {
170
+ const raw = await fs.readFile(configPath, "utf8");
171
+ return JSON.parse(raw);
172
+ }
173
+ catch {
174
+ return undefined;
175
+ }
176
+ };
177
+ const primary = await readConfig(mcodaDir);
178
+ if (primary)
179
+ return primary;
180
+ if (fallbackDir && fallbackDir !== mcodaDir) {
181
+ return readConfig(fallbackDir);
44
182
  }
183
+ return undefined;
45
184
  };
46
- const readWorkspaceConfig = async (mcodaDir) => {
47
- const configPath = path.join(mcodaDir, "config.json");
48
- try {
49
- const raw = await fs.readFile(configPath, "utf8");
50
- return JSON.parse(raw);
185
+ const applyWorkspaceEnvOverrides = (config) => {
186
+ if (!config)
187
+ return;
188
+ if (config.codexNoSandbox === true) {
189
+ process.env.MCODA_CODEX_NO_SANDBOX = "1";
190
+ return;
51
191
  }
52
- catch {
53
- return undefined;
192
+ if (config.codexNoSandbox === false && process.env.MCODA_CODEX_NO_SANDBOX === undefined) {
193
+ process.env.MCODA_CODEX_NO_SANDBOX = "0";
54
194
  }
55
195
  };
56
196
  const readWorkspaceIdentity = async (mcodaDir) => {
@@ -74,9 +214,13 @@ const looksLikeWorkspaceId = (value) => /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a
74
214
  const migrateWorkspaceDbIds = async (workspace, legacyIds) => {
75
215
  if (!legacyIds.length)
76
216
  return;
217
+ if (!(await fileExists(workspace.workspaceDbPath))) {
218
+ return;
219
+ }
220
+ let conn;
77
221
  try {
78
222
  const { Connection } = await import("@mcoda/db");
79
- const conn = await Connection.open(workspace.workspaceDbPath);
223
+ conn = await Connection.open(workspace.workspaceDbPath);
80
224
  const db = conn.db;
81
225
  const placeholders = legacyIds.map(() => "?").join(",");
82
226
  const params = [workspace.workspaceId, ...legacyIds];
@@ -84,11 +228,20 @@ const migrateWorkspaceDbIds = async (workspace, legacyIds) => {
84
228
  for (const table of tables) {
85
229
  await db.run(`UPDATE ${table} SET workspace_id = ? WHERE workspace_id IN (${placeholders})`, params);
86
230
  }
87
- await conn.close();
88
231
  }
89
232
  catch {
90
233
  /* best effort */
91
234
  }
235
+ finally {
236
+ if (conn) {
237
+ try {
238
+ await conn.close();
239
+ }
240
+ catch {
241
+ /* best effort */
242
+ }
243
+ }
244
+ }
92
245
  const updateJsonArray = async (filePath) => {
93
246
  try {
94
247
  const raw = await fs.readFile(filePath, "utf8");
@@ -111,12 +264,13 @@ const migrateWorkspaceDbIds = async (workspace, legacyIds) => {
111
264
  /* ignore */
112
265
  }
113
266
  };
114
- await updateJsonArray(path.join(workspace.workspaceRoot, ".mcoda", "command_runs.json"));
115
- await updateJsonArray(path.join(workspace.workspaceRoot, ".mcoda", "token_usage.json"));
267
+ await updateJsonArray(path.join(workspace.mcodaDir, "command_runs.json"));
268
+ await updateJsonArray(path.join(workspace.mcodaDir, "token_usage.json"));
116
269
  };
117
270
  export class WorkspaceResolver {
118
271
  static async resolveWorkspace(input) {
119
272
  const cwd = path.resolve(input.cwd ?? process.cwd());
273
+ const noRepoWrites = Boolean(input.noRepoWrites);
120
274
  let explicit = input.explicitWorkspace;
121
275
  let explicitPath;
122
276
  if (explicit) {
@@ -137,10 +291,13 @@ export class WorkspaceResolver {
137
291
  const fromMarker = await findWorkspaceMarker(explicitPath ?? cwd);
138
292
  const gitRoot = await findGitRoot(explicitPath ?? cwd);
139
293
  const workspaceRoot = explicitPath ?? fromMarker ?? gitRoot ?? cwd;
140
- const mcodaDir = path.join(workspaceRoot, ".mcoda");
294
+ const repoMcodaDir = path.join(workspaceRoot, ".mcoda");
295
+ const mcodaDir = PathHelper.getGlobalWorkspaceDir(workspaceRoot);
141
296
  await PathHelper.ensureDir(mcodaDir);
142
- await ensureGitignore(workspaceRoot);
143
- const existingIdentity = await readWorkspaceIdentity(mcodaDir);
297
+ await maybeCopyLegacyWorkspace(repoMcodaDir, mcodaDir);
298
+ const repoIdentity = await readWorkspaceIdentity(repoMcodaDir);
299
+ const globalIdentity = await readWorkspaceIdentity(mcodaDir);
300
+ const existingIdentity = globalIdentity ?? repoIdentity;
144
301
  let identity;
145
302
  let legacyIds = [];
146
303
  if (existingIdentity) {
@@ -151,6 +308,19 @@ export class WorkspaceResolver {
151
308
  legacyIds.push(workspaceRoot);
152
309
  updatedIdentity = true;
153
310
  }
311
+ if (repoIdentity) {
312
+ if (repoIdentity.id && repoIdentity.id !== existingIdentity.id) {
313
+ legacyIds.push(repoIdentity.id);
314
+ updatedIdentity = true;
315
+ }
316
+ if (repoIdentity.legacyIds?.length) {
317
+ legacyIds.push(...repoIdentity.legacyIds);
318
+ updatedIdentity = true;
319
+ }
320
+ if (!globalIdentity) {
321
+ updatedIdentity = true;
322
+ }
323
+ }
154
324
  if (!looksLikeWorkspaceId(existingIdentity.id)) {
155
325
  legacyIds.push(existingIdentity.id);
156
326
  identity = {
@@ -158,7 +328,7 @@ export class WorkspaceResolver {
158
328
  id: randomUUID(),
159
329
  legacyIds: Array.from(new Set(legacyIds)),
160
330
  };
161
- await writeWorkspaceIdentity(mcodaDir, identity);
331
+ updatedIdentity = true;
162
332
  }
163
333
  else {
164
334
  identity = {
@@ -168,9 +338,9 @@ export class WorkspaceResolver {
168
338
  if ((identity.legacyIds?.length ?? 0) !== existingLegacy.size) {
169
339
  updatedIdentity = true;
170
340
  }
171
- if (updatedIdentity) {
172
- await writeWorkspaceIdentity(mcodaDir, identity);
173
- }
341
+ }
342
+ if (updatedIdentity) {
343
+ await writeWorkspaceIdentity(mcodaDir, identity);
174
344
  }
175
345
  }
176
346
  else {
@@ -183,19 +353,23 @@ export class WorkspaceResolver {
183
353
  await writeWorkspaceIdentity(mcodaDir, identity);
184
354
  }
185
355
  const legacyWorkspaceIds = Array.from(new Set([...(identity.legacyIds ?? []), workspaceRoot].filter(Boolean)));
186
- const config = await readWorkspaceConfig(mcodaDir);
356
+ const config = await readWorkspaceConfig(mcodaDir, repoMcodaDir);
357
+ applyWorkspaceEnvOverrides(config);
187
358
  const resolution = {
188
359
  workspaceRoot,
189
360
  workspaceId: identity.id,
190
361
  id: identity.id,
191
362
  legacyWorkspaceIds,
192
363
  mcodaDir,
193
- workspaceDbPath: PathHelper.getWorkspaceDbPath(workspaceRoot),
364
+ workspaceDbPath: path.join(mcodaDir, "mcoda.db"),
194
365
  globalDbPath: PathHelper.getGlobalDbPath(),
366
+ noRepoWrites,
195
367
  config,
196
368
  };
197
369
  // Best-effort migration of workspace_id columns and JSON logs from legacy IDs.
198
- await migrateWorkspaceDbIds(resolution, legacyWorkspaceIds.filter((id) => id !== identity.id));
370
+ if (!noRepoWrites) {
371
+ await migrateWorkspaceDbIds(resolution, legacyWorkspaceIds.filter((id) => id !== identity.id));
372
+ }
199
373
  return resolution;
200
374
  }
201
375
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcoda/core",
3
- "version": "0.1.8",
3
+ "version": "0.1.11",
4
4
  "description": "Core services and APIs for the mcoda CLI.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,10 +32,11 @@
32
32
  "dependencies": {
33
33
  "@apidevtools/swagger-parser": "^10.1.0",
34
34
  "yaml": "^2.4.2",
35
- "@mcoda/shared": "0.1.8",
36
- "@mcoda/agents": "0.1.8",
37
- "@mcoda/integrations": "0.1.8",
38
- "@mcoda/db": "0.1.8"
35
+ "@mcoda/db": "0.1.11",
36
+ "@mcoda/shared": "0.1.11",
37
+ "@mcoda/agents": "0.1.11",
38
+ "@mcoda/generators": "0.1.11",
39
+ "@mcoda/integrations": "0.1.11"
39
40
  },
40
41
  "scripts": {
41
42
  "build": "tsc -p tsconfig.json",