@mcoda/core 0.1.9 → 0.1.12

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 (204) hide show
  1. package/README.md +2 -2
  2. package/dist/api/AgentsApi.d.ts +1 -0
  3. package/dist/api/AgentsApi.d.ts.map +1 -1
  4. package/dist/api/AgentsApi.js +136 -11
  5. package/dist/api/QaTasksApi.d.ts.map +1 -1
  6. package/dist/api/QaTasksApi.js +4 -0
  7. package/dist/prompts/PdrPrompts.d.ts.map +1 -1
  8. package/dist/prompts/PdrPrompts.js +6 -0
  9. package/dist/prompts/SdsPrompts.d.ts.map +1 -1
  10. package/dist/prompts/SdsPrompts.js +7 -0
  11. package/dist/services/agents/AgentRatingService.d.ts +19 -0
  12. package/dist/services/agents/AgentRatingService.d.ts.map +1 -1
  13. package/dist/services/agents/AgentRatingService.js +66 -2
  14. package/dist/services/agents/GatewayAgentService.d.ts +8 -0
  15. package/dist/services/agents/GatewayAgentService.d.ts.map +1 -1
  16. package/dist/services/agents/GatewayAgentService.js +462 -65
  17. package/dist/services/agents/GatewayHandoff.d.ts +5 -1
  18. package/dist/services/agents/GatewayHandoff.d.ts.map +1 -1
  19. package/dist/services/agents/GatewayHandoff.js +65 -32
  20. package/dist/services/agents/RoutingService.d.ts +1 -0
  21. package/dist/services/agents/RoutingService.d.ts.map +1 -1
  22. package/dist/services/agents/RoutingService.js +4 -4
  23. package/dist/services/backlog/BacklogService.d.ts +23 -0
  24. package/dist/services/backlog/BacklogService.d.ts.map +1 -1
  25. package/dist/services/backlog/BacklogService.js +62 -7
  26. package/dist/services/backlog/TaskOrderingHeuristics.d.ts +12 -0
  27. package/dist/services/backlog/TaskOrderingHeuristics.d.ts.map +1 -0
  28. package/dist/services/backlog/TaskOrderingHeuristics.js +56 -0
  29. package/dist/services/backlog/TaskOrderingService.d.ts +16 -4
  30. package/dist/services/backlog/TaskOrderingService.d.ts.map +1 -1
  31. package/dist/services/backlog/TaskOrderingService.js +529 -73
  32. package/dist/services/docs/DocInventory.d.ts +11 -0
  33. package/dist/services/docs/DocInventory.d.ts.map +1 -0
  34. package/dist/services/docs/DocInventory.js +230 -0
  35. package/dist/services/docs/DocgenRunContext.d.ts +59 -0
  36. package/dist/services/docs/DocgenRunContext.d.ts.map +1 -0
  37. package/dist/services/docs/DocgenRunContext.js +4 -0
  38. package/dist/services/docs/DocsService.d.ts +59 -2
  39. package/dist/services/docs/DocsService.d.ts.map +1 -1
  40. package/dist/services/docs/DocsService.js +1701 -48
  41. package/dist/services/docs/alignment/DocAlignmentGraph.d.ts +23 -0
  42. package/dist/services/docs/alignment/DocAlignmentGraph.d.ts.map +1 -0
  43. package/dist/services/docs/alignment/DocAlignmentGraph.js +78 -0
  44. package/dist/services/docs/alignment/DocAlignmentPatcher.d.ts +19 -0
  45. package/dist/services/docs/alignment/DocAlignmentPatcher.d.ts.map +1 -0
  46. package/dist/services/docs/alignment/DocAlignmentPatcher.js +222 -0
  47. package/dist/services/docs/patch/DocPatchEngine.d.ts +57 -0
  48. package/dist/services/docs/patch/DocPatchEngine.d.ts.map +1 -0
  49. package/dist/services/docs/patch/DocPatchEngine.js +331 -0
  50. package/dist/services/docs/review/Glossary.d.ts +16 -0
  51. package/dist/services/docs/review/Glossary.d.ts.map +1 -0
  52. package/dist/services/docs/review/Glossary.js +47 -0
  53. package/dist/services/docs/review/ReviewReportRenderer.d.ts +3 -0
  54. package/dist/services/docs/review/ReviewReportRenderer.d.ts.map +1 -0
  55. package/dist/services/docs/review/ReviewReportRenderer.js +133 -0
  56. package/dist/services/docs/review/ReviewReportSchema.d.ts +39 -0
  57. package/dist/services/docs/review/ReviewReportSchema.d.ts.map +1 -0
  58. package/dist/services/docs/review/ReviewReportSchema.js +47 -0
  59. package/dist/services/docs/review/ReviewTypes.d.ts +76 -0
  60. package/dist/services/docs/review/ReviewTypes.d.ts.map +1 -0
  61. package/dist/services/docs/review/ReviewTypes.js +94 -0
  62. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.d.ts +7 -0
  63. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.d.ts.map +1 -0
  64. package/dist/services/docs/review/gates/AdminOpenApiSpecGate.js +93 -0
  65. package/dist/services/docs/review/gates/ApiPathConsistencyGate.d.ts +7 -0
  66. package/dist/services/docs/review/gates/ApiPathConsistencyGate.d.ts.map +1 -0
  67. package/dist/services/docs/review/gates/ApiPathConsistencyGate.js +308 -0
  68. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.d.ts +8 -0
  69. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.d.ts.map +1 -0
  70. package/dist/services/docs/review/gates/BuildReadyCompletenessGate.js +278 -0
  71. package/dist/services/docs/review/gates/DeploymentBlueprintGate.d.ts +8 -0
  72. package/dist/services/docs/review/gates/DeploymentBlueprintGate.d.ts.map +1 -0
  73. package/dist/services/docs/review/gates/DeploymentBlueprintGate.js +487 -0
  74. package/dist/services/docs/review/gates/NoMaybesGate.d.ts +8 -0
  75. package/dist/services/docs/review/gates/NoMaybesGate.d.ts.map +1 -0
  76. package/dist/services/docs/review/gates/NoMaybesGate.js +145 -0
  77. package/dist/services/docs/review/gates/OpenApiCoverageGate.d.ts +7 -0
  78. package/dist/services/docs/review/gates/OpenApiCoverageGate.d.ts.map +1 -0
  79. package/dist/services/docs/review/gates/OpenApiCoverageGate.js +266 -0
  80. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.d.ts +7 -0
  81. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.d.ts.map +1 -0
  82. package/dist/services/docs/review/gates/OpenApiSchemaSanityGate.js +59 -0
  83. package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts +7 -0
  84. package/dist/services/docs/review/gates/OpenQuestionsGate.d.ts.map +1 -0
  85. package/dist/services/docs/review/gates/OpenQuestionsGate.js +200 -0
  86. package/dist/services/docs/review/gates/PdrInterfacesGate.d.ts +7 -0
  87. package/dist/services/docs/review/gates/PdrInterfacesGate.d.ts.map +1 -0
  88. package/dist/services/docs/review/gates/PdrInterfacesGate.js +159 -0
  89. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.d.ts +8 -0
  90. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.d.ts.map +1 -0
  91. package/dist/services/docs/review/gates/PdrOpenQuestionsGate.js +129 -0
  92. package/dist/services/docs/review/gates/PdrOwnershipGate.d.ts +7 -0
  93. package/dist/services/docs/review/gates/PdrOwnershipGate.d.ts.map +1 -0
  94. package/dist/services/docs/review/gates/PdrOwnershipGate.js +169 -0
  95. package/dist/services/docs/review/gates/PlaceholderArtifactGate.d.ts +10 -0
  96. package/dist/services/docs/review/gates/PlaceholderArtifactGate.d.ts.map +1 -0
  97. package/dist/services/docs/review/gates/PlaceholderArtifactGate.js +261 -0
  98. package/dist/services/docs/review/gates/RfpConsentGate.d.ts +6 -0
  99. package/dist/services/docs/review/gates/RfpConsentGate.d.ts.map +1 -0
  100. package/dist/services/docs/review/gates/RfpConsentGate.js +127 -0
  101. package/dist/services/docs/review/gates/RfpDefinitionGate.d.ts +7 -0
  102. package/dist/services/docs/review/gates/RfpDefinitionGate.d.ts.map +1 -0
  103. package/dist/services/docs/review/gates/RfpDefinitionGate.js +173 -0
  104. package/dist/services/docs/review/gates/SdsAdaptersGate.d.ts +7 -0
  105. package/dist/services/docs/review/gates/SdsAdaptersGate.d.ts.map +1 -0
  106. package/dist/services/docs/review/gates/SdsAdaptersGate.js +196 -0
  107. package/dist/services/docs/review/gates/SdsDecisionsGate.d.ts +7 -0
  108. package/dist/services/docs/review/gates/SdsDecisionsGate.d.ts.map +1 -0
  109. package/dist/services/docs/review/gates/SdsDecisionsGate.js +89 -0
  110. package/dist/services/docs/review/gates/SdsOpsGate.d.ts +7 -0
  111. package/dist/services/docs/review/gates/SdsOpsGate.d.ts.map +1 -0
  112. package/dist/services/docs/review/gates/SdsOpsGate.js +162 -0
  113. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.d.ts +7 -0
  114. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.d.ts.map +1 -0
  115. package/dist/services/docs/review/gates/SdsPolicyTelemetryGate.js +166 -0
  116. package/dist/services/docs/review/gates/SqlRequiredTablesGate.d.ts +7 -0
  117. package/dist/services/docs/review/gates/SqlRequiredTablesGate.d.ts.map +1 -0
  118. package/dist/services/docs/review/gates/SqlRequiredTablesGate.js +273 -0
  119. package/dist/services/docs/review/gates/SqlSyntaxGate.d.ts +7 -0
  120. package/dist/services/docs/review/gates/SqlSyntaxGate.d.ts.map +1 -0
  121. package/dist/services/docs/review/gates/SqlSyntaxGate.js +203 -0
  122. package/dist/services/docs/review/gates/TerminologyNormalizationGate.d.ts +9 -0
  123. package/dist/services/docs/review/gates/TerminologyNormalizationGate.d.ts.map +1 -0
  124. package/dist/services/docs/review/gates/TerminologyNormalizationGate.js +217 -0
  125. package/dist/services/docs/review/glossary.json +47 -0
  126. package/dist/services/estimate/EstimateService.d.ts +2 -0
  127. package/dist/services/estimate/EstimateService.d.ts.map +1 -1
  128. package/dist/services/estimate/EstimateService.js +66 -18
  129. package/dist/services/estimate/VelocityService.d.ts +4 -0
  130. package/dist/services/estimate/VelocityService.d.ts.map +1 -1
  131. package/dist/services/estimate/VelocityService.js +179 -36
  132. package/dist/services/estimate/types.d.ts +1 -0
  133. package/dist/services/estimate/types.d.ts.map +1 -1
  134. package/dist/services/execution/GatewayTrioService.d.ts +71 -4
  135. package/dist/services/execution/GatewayTrioService.d.ts.map +1 -1
  136. package/dist/services/execution/GatewayTrioService.js +1695 -328
  137. package/dist/services/execution/QaApiRunner.d.ts +30 -0
  138. package/dist/services/execution/QaApiRunner.d.ts.map +1 -0
  139. package/dist/services/execution/QaApiRunner.js +881 -0
  140. package/dist/services/execution/QaFollowupService.d.ts +1 -0
  141. package/dist/services/execution/QaFollowupService.d.ts.map +1 -1
  142. package/dist/services/execution/QaFollowupService.js +8 -2
  143. package/dist/services/execution/QaPlanValidator.d.ts +10 -0
  144. package/dist/services/execution/QaPlanValidator.d.ts.map +1 -0
  145. package/dist/services/execution/QaPlanValidator.js +128 -0
  146. package/dist/services/execution/QaProfileService.d.ts +21 -1
  147. package/dist/services/execution/QaProfileService.d.ts.map +1 -1
  148. package/dist/services/execution/QaProfileService.js +214 -29
  149. package/dist/services/execution/QaTasksService.d.ts +41 -1
  150. package/dist/services/execution/QaTasksService.d.ts.map +1 -1
  151. package/dist/services/execution/QaTasksService.js +2851 -500
  152. package/dist/services/execution/QaTestCommandBuilder.d.ts +51 -0
  153. package/dist/services/execution/QaTestCommandBuilder.d.ts.map +1 -0
  154. package/dist/services/execution/QaTestCommandBuilder.js +495 -0
  155. package/dist/services/execution/TaskSelectionService.d.ts +4 -2
  156. package/dist/services/execution/TaskSelectionService.d.ts.map +1 -1
  157. package/dist/services/execution/TaskSelectionService.js +144 -28
  158. package/dist/services/execution/TaskStateService.d.ts +19 -6
  159. package/dist/services/execution/TaskStateService.d.ts.map +1 -1
  160. package/dist/services/execution/TaskStateService.js +128 -13
  161. package/dist/services/execution/WorkOnTasksService.d.ts +19 -2
  162. package/dist/services/execution/WorkOnTasksService.d.ts.map +1 -1
  163. package/dist/services/execution/WorkOnTasksService.js +3913 -1225
  164. package/dist/services/jobs/JobInsightsService.d.ts +4 -0
  165. package/dist/services/jobs/JobInsightsService.d.ts.map +1 -1
  166. package/dist/services/jobs/JobInsightsService.js +51 -5
  167. package/dist/services/jobs/JobResumeService.d.ts.map +1 -1
  168. package/dist/services/jobs/JobResumeService.js +23 -10
  169. package/dist/services/jobs/JobService.d.ts +56 -4
  170. package/dist/services/jobs/JobService.d.ts.map +1 -1
  171. package/dist/services/jobs/JobService.js +232 -1
  172. package/dist/services/openapi/OpenApiService.d.ts +41 -0
  173. package/dist/services/openapi/OpenApiService.d.ts.map +1 -1
  174. package/dist/services/openapi/OpenApiService.js +889 -98
  175. package/dist/services/planning/CreateTasksService.d.ts +15 -0
  176. package/dist/services/planning/CreateTasksService.d.ts.map +1 -1
  177. package/dist/services/planning/CreateTasksService.js +311 -6
  178. package/dist/services/planning/RefineTasksService.d.ts +4 -0
  179. package/dist/services/planning/RefineTasksService.d.ts.map +1 -1
  180. package/dist/services/planning/RefineTasksService.js +225 -24
  181. package/dist/services/review/CodeReviewService.d.ts +4 -0
  182. package/dist/services/review/CodeReviewService.d.ts.map +1 -1
  183. package/dist/services/review/CodeReviewService.js +778 -232
  184. package/dist/services/review/ReviewNormalizer.d.ts +9 -0
  185. package/dist/services/review/ReviewNormalizer.d.ts.map +1 -0
  186. package/dist/services/review/ReviewNormalizer.js +147 -0
  187. package/dist/services/shared/AuthErrors.d.ts +3 -0
  188. package/dist/services/shared/AuthErrors.d.ts.map +1 -0
  189. package/dist/services/shared/AuthErrors.js +17 -0
  190. package/dist/services/shared/DocdexGuidance.d.ts +7 -0
  191. package/dist/services/shared/DocdexGuidance.d.ts.map +1 -0
  192. package/dist/services/shared/DocdexGuidance.js +12 -0
  193. package/dist/services/shared/ProjectGuidance.d.ts +12 -1
  194. package/dist/services/shared/ProjectGuidance.d.ts.map +1 -1
  195. package/dist/services/shared/ProjectGuidance.js +64 -7
  196. package/dist/services/system/ToolDenylist.d.ts +13 -0
  197. package/dist/services/system/ToolDenylist.d.ts.map +1 -0
  198. package/dist/services/system/ToolDenylist.js +85 -0
  199. package/dist/services/telemetry/TelemetryService.d.ts.map +1 -1
  200. package/dist/services/telemetry/TelemetryService.js +39 -7
  201. package/dist/workspace/WorkspaceManager.d.ts +22 -0
  202. package/dist/workspace/WorkspaceManager.d.ts.map +1 -1
  203. package/dist/workspace/WorkspaceManager.js +203 -32
  204. package/package.json +6 -5
@@ -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) => {
@@ -77,9 +217,10 @@ const migrateWorkspaceDbIds = async (workspace, legacyIds) => {
77
217
  if (!(await fileExists(workspace.workspaceDbPath))) {
78
218
  return;
79
219
  }
220
+ let conn;
80
221
  try {
81
222
  const { Connection } = await import("@mcoda/db");
82
- const conn = await Connection.open(workspace.workspaceDbPath);
223
+ conn = await Connection.open(workspace.workspaceDbPath);
83
224
  const db = conn.db;
84
225
  const placeholders = legacyIds.map(() => "?").join(",");
85
226
  const params = [workspace.workspaceId, ...legacyIds];
@@ -87,11 +228,20 @@ const migrateWorkspaceDbIds = async (workspace, legacyIds) => {
87
228
  for (const table of tables) {
88
229
  await db.run(`UPDATE ${table} SET workspace_id = ? WHERE workspace_id IN (${placeholders})`, params);
89
230
  }
90
- await conn.close();
91
231
  }
92
232
  catch {
93
233
  /* best effort */
94
234
  }
235
+ finally {
236
+ if (conn) {
237
+ try {
238
+ await conn.close();
239
+ }
240
+ catch {
241
+ /* best effort */
242
+ }
243
+ }
244
+ }
95
245
  const updateJsonArray = async (filePath) => {
96
246
  try {
97
247
  const raw = await fs.readFile(filePath, "utf8");
@@ -114,12 +264,13 @@ const migrateWorkspaceDbIds = async (workspace, legacyIds) => {
114
264
  /* ignore */
115
265
  }
116
266
  };
117
- await updateJsonArray(path.join(workspace.workspaceRoot, ".mcoda", "command_runs.json"));
118
- 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"));
119
269
  };
120
270
  export class WorkspaceResolver {
121
271
  static async resolveWorkspace(input) {
122
272
  const cwd = path.resolve(input.cwd ?? process.cwd());
273
+ const noRepoWrites = Boolean(input.noRepoWrites);
123
274
  let explicit = input.explicitWorkspace;
124
275
  let explicitPath;
125
276
  if (explicit) {
@@ -140,10 +291,13 @@ export class WorkspaceResolver {
140
291
  const fromMarker = await findWorkspaceMarker(explicitPath ?? cwd);
141
292
  const gitRoot = await findGitRoot(explicitPath ?? cwd);
142
293
  const workspaceRoot = explicitPath ?? fromMarker ?? gitRoot ?? cwd;
143
- const mcodaDir = path.join(workspaceRoot, ".mcoda");
294
+ const repoMcodaDir = path.join(workspaceRoot, ".mcoda");
295
+ const mcodaDir = PathHelper.getGlobalWorkspaceDir(workspaceRoot);
144
296
  await PathHelper.ensureDir(mcodaDir);
145
- await ensureGitignore(workspaceRoot);
146
- 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;
147
301
  let identity;
148
302
  let legacyIds = [];
149
303
  if (existingIdentity) {
@@ -154,6 +308,19 @@ export class WorkspaceResolver {
154
308
  legacyIds.push(workspaceRoot);
155
309
  updatedIdentity = true;
156
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
+ }
157
324
  if (!looksLikeWorkspaceId(existingIdentity.id)) {
158
325
  legacyIds.push(existingIdentity.id);
159
326
  identity = {
@@ -161,7 +328,7 @@ export class WorkspaceResolver {
161
328
  id: randomUUID(),
162
329
  legacyIds: Array.from(new Set(legacyIds)),
163
330
  };
164
- await writeWorkspaceIdentity(mcodaDir, identity);
331
+ updatedIdentity = true;
165
332
  }
166
333
  else {
167
334
  identity = {
@@ -171,9 +338,9 @@ export class WorkspaceResolver {
171
338
  if ((identity.legacyIds?.length ?? 0) !== existingLegacy.size) {
172
339
  updatedIdentity = true;
173
340
  }
174
- if (updatedIdentity) {
175
- await writeWorkspaceIdentity(mcodaDir, identity);
176
- }
341
+ }
342
+ if (updatedIdentity) {
343
+ await writeWorkspaceIdentity(mcodaDir, identity);
177
344
  }
178
345
  }
179
346
  else {
@@ -186,19 +353,23 @@ export class WorkspaceResolver {
186
353
  await writeWorkspaceIdentity(mcodaDir, identity);
187
354
  }
188
355
  const legacyWorkspaceIds = Array.from(new Set([...(identity.legacyIds ?? []), workspaceRoot].filter(Boolean)));
189
- const config = await readWorkspaceConfig(mcodaDir);
356
+ const config = await readWorkspaceConfig(mcodaDir, repoMcodaDir);
357
+ applyWorkspaceEnvOverrides(config);
190
358
  const resolution = {
191
359
  workspaceRoot,
192
360
  workspaceId: identity.id,
193
361
  id: identity.id,
194
362
  legacyWorkspaceIds,
195
363
  mcodaDir,
196
- workspaceDbPath: PathHelper.getWorkspaceDbPath(workspaceRoot),
364
+ workspaceDbPath: path.join(mcodaDir, "mcoda.db"),
197
365
  globalDbPath: PathHelper.getGlobalDbPath(),
366
+ noRepoWrites,
198
367
  config,
199
368
  };
200
369
  // Best-effort migration of workspace_id columns and JSON logs from legacy IDs.
201
- await migrateWorkspaceDbIds(resolution, legacyWorkspaceIds.filter((id) => id !== identity.id));
370
+ if (!noRepoWrites) {
371
+ await migrateWorkspaceDbIds(resolution, legacyWorkspaceIds.filter((id) => id !== identity.id));
372
+ }
202
373
  return resolution;
203
374
  }
204
375
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcoda/core",
3
- "version": "0.1.9",
3
+ "version": "0.1.12",
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/db": "0.1.9",
36
- "@mcoda/shared": "0.1.9",
37
- "@mcoda/agents": "0.1.9",
38
- "@mcoda/integrations": "0.1.9"
35
+ "@mcoda/shared": "0.1.12",
36
+ "@mcoda/agents": "0.1.12",
37
+ "@mcoda/generators": "0.1.12",
38
+ "@mcoda/integrations": "0.1.12",
39
+ "@mcoda/db": "0.1.12"
39
40
  },
40
41
  "scripts": {
41
42
  "build": "tsc -p tsconfig.json",