@mastra/code-sdk 1.0.3-alpha.0 → 1.1.0-alpha.2

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 (258) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/acp/agent.js +155 -167
  3. package/dist/acp/agent.js.map +1 -1
  4. package/dist/acp/event-mapper.js +193 -168
  5. package/dist/acp/event-mapper.js.map +1 -1
  6. package/dist/acp/index.js +60 -49
  7. package/dist/acp/index.js.map +1 -1
  8. package/dist/acp/server.js +31 -30
  9. package/dist/acp/server.js.map +1 -1
  10. package/dist/acp.js +1 -4
  11. package/dist/agents/credential-resolver.js +40 -29
  12. package/dist/agents/credential-resolver.js.map +1 -1
  13. package/dist/agents/custom-provider-source.js +16 -9
  14. package/dist/agents/custom-provider-source.js.map +1 -1
  15. package/dist/agents/instructions.js +27 -36
  16. package/dist/agents/instructions.js.map +1 -1
  17. package/dist/agents/mastracode-gateway.js +355 -428
  18. package/dist/agents/mastracode-gateway.js.map +1 -1
  19. package/dist/agents/memory.js +87 -78
  20. package/dist/agents/memory.js.map +1 -1
  21. package/dist/agents/model.js +114 -119
  22. package/dist/agents/model.js.map +1 -1
  23. package/dist/agents/modes/build.js +12 -13
  24. package/dist/agents/modes/build.js.map +1 -1
  25. package/dist/agents/modes/explore.js +14 -13
  26. package/dist/agents/modes/explore.js.map +1 -1
  27. package/dist/agents/modes/plan.js +14 -15
  28. package/dist/agents/modes/plan.js.map +1 -1
  29. package/dist/agents/prompts/agent-instructions.js +78 -69
  30. package/dist/agents/prompts/agent-instructions.js.map +1 -1
  31. package/dist/agents/prompts/build.js +19 -16
  32. package/dist/agents/prompts/build.js.map +1 -1
  33. package/dist/agents/prompts/fast.js +8 -4
  34. package/dist/agents/prompts/fast.js.map +1 -1
  35. package/dist/agents/prompts/index.js +48 -47
  36. package/dist/agents/prompts/index.js.map +1 -1
  37. package/dist/agents/prompts/model.js +6 -5
  38. package/dist/agents/prompts/model.js.map +1 -1
  39. package/dist/agents/prompts/plan.js +20 -16
  40. package/dist/agents/prompts/plan.js.map +1 -1
  41. package/dist/agents/prompts/tool-guidance.js +77 -109
  42. package/dist/agents/prompts/tool-guidance.js.map +1 -1
  43. package/dist/agents/sandbox-filesystem.js +245 -259
  44. package/dist/agents/sandbox-filesystem.js.map +1 -1
  45. package/dist/agents/sandbox-reattach.js +9 -11
  46. package/dist/agents/sandbox-reattach.js.map +1 -1
  47. package/dist/agents/thread-caveman-state.js +92 -81
  48. package/dist/agents/thread-caveman-state.js.map +1 -1
  49. package/dist/agents/tool-availability.js +62 -80
  50. package/dist/agents/tool-availability.js.map +1 -1
  51. package/dist/agents/tools.js +99 -139
  52. package/dist/agents/tools.js.map +1 -1
  53. package/dist/agents/workspace.js +232 -225
  54. package/dist/agents/workspace.js.map +1 -1
  55. package/dist/analytics.js +139 -128
  56. package/dist/analytics.js.map +1 -1
  57. package/dist/auth/authorization-input.js +39 -25
  58. package/dist/auth/authorization-input.js.map +1 -1
  59. package/dist/auth/device-code.js +112 -80
  60. package/dist/auth/device-code.js.map +1 -1
  61. package/dist/auth/index.js +2 -9
  62. package/dist/auth/pkce.js +27 -16
  63. package/dist/auth/pkce.js.map +1 -1
  64. package/dist/auth/providers/anthropic.js +107 -93
  65. package/dist/auth/providers/anthropic.js.map +1 -1
  66. package/dist/auth/providers/github-copilot.js +304 -293
  67. package/dist/auth/providers/github-copilot.js.map +1 -1
  68. package/dist/auth/providers/openai-codex.js +442 -460
  69. package/dist/auth/providers/openai-codex.js.map +1 -1
  70. package/dist/auth/providers/xai.js +179 -145
  71. package/dist/auth/providers/xai.js.map +1 -1
  72. package/dist/auth/storage.js +182 -175
  73. package/dist/auth/storage.js.map +1 -1
  74. package/dist/auth/types.js +1 -1
  75. package/dist/clipboard/index.js +206 -172
  76. package/dist/clipboard/index.js.map +1 -1
  77. package/dist/constants.js +11 -16
  78. package/dist/constants.js.map +1 -1
  79. package/dist/error-classification.js +19 -11
  80. package/dist/error-classification.js.map +1 -1
  81. package/dist/evals/context-builder.js +145 -104
  82. package/dist/evals/context-builder.js.map +1 -1
  83. package/dist/evals/index.js +4 -7
  84. package/dist/evals/scorers/classify-command.js +62 -41
  85. package/dist/evals/scorers/classify-command.js.map +1 -1
  86. package/dist/evals/scorers/efficiency.js +239 -181
  87. package/dist/evals/scorers/efficiency.js.map +1 -1
  88. package/dist/evals/scorers/extract-tools.js +51 -47
  89. package/dist/evals/scorers/extract-tools.js.map +1 -1
  90. package/dist/evals/scorers/index.js +1 -5
  91. package/dist/evals/scorers/outcome.js +321 -212
  92. package/dist/evals/scorers/outcome.js.map +1 -1
  93. package/dist/goal-manager.js +266 -261
  94. package/dist/goal-manager.js.map +1 -1
  95. package/dist/goal-signal.js +14 -13
  96. package/dist/goal-signal.js.map +1 -1
  97. package/dist/headless/cli.js +153 -154
  98. package/dist/headless/cli.js.map +1 -1
  99. package/dist/headless/flags.js +180 -178
  100. package/dist/headless/flags.js.map +1 -1
  101. package/dist/headless/format.js +72 -71
  102. package/dist/headless/format.js.map +1 -1
  103. package/dist/headless/index.js +5 -31
  104. package/dist/headless/policy.js +35 -31
  105. package/dist/headless/policy.js.map +1 -1
  106. package/dist/headless/run-mc.js +332 -334
  107. package/dist/headless/run-mc.js.map +1 -1
  108. package/dist/headless/types.js +16 -7
  109. package/dist/headless/types.js.map +1 -1
  110. package/dist/hooks/config.js +56 -61
  111. package/dist/hooks/config.js.map +1 -1
  112. package/dist/hooks/executor.js +118 -116
  113. package/dist/hooks/executor.js.map +1 -1
  114. package/dist/hooks/index.js +4 -15
  115. package/dist/hooks/manager.js +221 -280
  116. package/dist/hooks/manager.js.map +1 -1
  117. package/dist/hooks/types.js +5 -4
  118. package/dist/hooks/types.js.map +1 -1
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +632 -712
  121. package/dist/index.js.map +1 -1
  122. package/dist/ipc/ipc-reporter.js +19 -22
  123. package/dist/ipc/ipc-reporter.js.map +1 -1
  124. package/dist/lsp/client.js +248 -306
  125. package/dist/lsp/client.js.map +1 -1
  126. package/dist/lsp/index.js +1 -6
  127. package/dist/lsp/language.js +39 -43
  128. package/dist/lsp/language.js.map +1 -1
  129. package/dist/lsp/manager.js +78 -93
  130. package/dist/lsp/manager.js.map +1 -1
  131. package/dist/lsp/server.js +151 -120
  132. package/dist/lsp/server.js.map +1 -1
  133. package/dist/lsp/workspace.js +50 -47
  134. package/dist/lsp/workspace.js.map +1 -1
  135. package/dist/mcp/config.js +210 -199
  136. package/dist/mcp/config.js.map +1 -1
  137. package/dist/mcp/index.js +2 -9
  138. package/dist/mcp/manager.js +482 -475
  139. package/dist/mcp/manager.js.map +1 -1
  140. package/dist/mcp/types.js +1 -1
  141. package/dist/onboarding/custom-packs.js +14 -17
  142. package/dist/onboarding/custom-packs.js.map +1 -1
  143. package/dist/onboarding/custom-providers.js +22 -20
  144. package/dist/onboarding/custom-providers.js.map +1 -1
  145. package/dist/onboarding/index.d.ts +1 -1
  146. package/dist/onboarding/index.d.ts.map +1 -1
  147. package/dist/onboarding/index.js +3 -21
  148. package/dist/onboarding/om-settings.d.ts +5 -0
  149. package/dist/onboarding/om-settings.d.ts.map +1 -1
  150. package/dist/onboarding/om-settings.js +41 -20
  151. package/dist/onboarding/om-settings.js.map +1 -1
  152. package/dist/onboarding/packs.d.ts +4 -6
  153. package/dist/onboarding/packs.d.ts.map +1 -1
  154. package/dist/onboarding/packs.js +154 -105
  155. package/dist/onboarding/packs.js.map +1 -1
  156. package/dist/onboarding/settings.js +575 -517
  157. package/dist/onboarding/settings.js.map +1 -1
  158. package/dist/permissions.js +112 -99
  159. package/dist/permissions.js.map +1 -1
  160. package/dist/plugin.js +21 -23
  161. package/dist/plugin.js.map +1 -1
  162. package/dist/plugins/dependencies.js +64 -87
  163. package/dist/plugins/dependencies.js.map +1 -1
  164. package/dist/plugins/install.js +159 -169
  165. package/dist/plugins/install.js.map +1 -1
  166. package/dist/plugins/loader.js +170 -185
  167. package/dist/plugins/loader.js.map +1 -1
  168. package/dist/plugins/manager.js +374 -380
  169. package/dist/plugins/manager.js.map +1 -1
  170. package/dist/plugins/manifest.js +38 -63
  171. package/dist/plugins/manifest.js.map +1 -1
  172. package/dist/plugins/package-link.js +48 -64
  173. package/dist/plugins/package-link.js.map +1 -1
  174. package/dist/plugins/paths.js +18 -19
  175. package/dist/plugins/paths.js.map +1 -1
  176. package/dist/plugins/registry.js +97 -81
  177. package/dist/plugins/registry.js.map +1 -1
  178. package/dist/plugins/scaffold.js +62 -98
  179. package/dist/plugins/scaffold.js.map +1 -1
  180. package/dist/plugins/types.js +1 -1
  181. package/dist/processors/plan-rejection-abort.js +45 -44
  182. package/dist/processors/plan-rejection-abort.js.map +1 -1
  183. package/dist/providers/amazon-bedrock-gateway.js +134 -125
  184. package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
  185. package/dist/providers/amazon-bedrock.js +68 -47
  186. package/dist/providers/amazon-bedrock.js.map +1 -1
  187. package/dist/providers/claude-max.js +153 -133
  188. package/dist/providers/claude-max.js.map +1 -1
  189. package/dist/providers/github-copilot.js +232 -230
  190. package/dist/providers/github-copilot.js.map +1 -1
  191. package/dist/providers/openai-codex.js +271 -260
  192. package/dist/providers/openai-codex.js.map +1 -1
  193. package/dist/providers/xai.js +57 -50
  194. package/dist/providers/xai.js.map +1 -1
  195. package/dist/schema.js +91 -89
  196. package/dist/schema.js.map +1 -1
  197. package/dist/theme-palette.js +18 -14
  198. package/dist/theme-palette.js.map +1 -1
  199. package/dist/tool-names.js +46 -37
  200. package/dist/tool-names.js.map +1 -1
  201. package/dist/tools/index.js +2 -8
  202. package/dist/tools/request-sandbox-access.js +71 -80
  203. package/dist/tools/request-sandbox-access.js.map +1 -1
  204. package/dist/tools/utils.js +26 -16
  205. package/dist/tools/utils.js.map +1 -1
  206. package/dist/tools/web-search.js +51 -55
  207. package/dist/tools/web-search.js.map +1 -1
  208. package/dist/utils/binaries.js +65 -61
  209. package/dist/utils/binaries.js.map +1 -1
  210. package/dist/utils/debug-log.js +51 -47
  211. package/dist/utils/debug-log.js.map +1 -1
  212. package/dist/utils/errors.js +157 -192
  213. package/dist/utils/errors.js.map +1 -1
  214. package/dist/utils/gateway-sync.js +49 -37
  215. package/dist/utils/gateway-sync.js.map +1 -1
  216. package/dist/utils/path-security.js +7 -6
  217. package/dist/utils/path-security.js.map +1 -1
  218. package/dist/utils/plan-diff.js +58 -39
  219. package/dist/utils/plan-diff.js.map +1 -1
  220. package/dist/utils/plans.js +92 -74
  221. package/dist/utils/plans.js.map +1 -1
  222. package/dist/utils/project.js +318 -256
  223. package/dist/utils/project.js.map +1 -1
  224. package/dist/utils/signals-pubsub.js +117 -99
  225. package/dist/utils/signals-pubsub.js.map +1 -1
  226. package/dist/utils/slash-command-loader.js +118 -154
  227. package/dist/utils/slash-command-loader.js.map +1 -1
  228. package/dist/utils/slash-command-processor.js +92 -83
  229. package/dist/utils/slash-command-processor.js.map +1 -1
  230. package/dist/utils/stdin-pipe.js +87 -63
  231. package/dist/utils/stdin-pipe.js.map +1 -1
  232. package/dist/utils/storage-factory.js +104 -84
  233. package/dist/utils/storage-factory.js.map +1 -1
  234. package/dist/utils/storage-maintenance.js +249 -211
  235. package/dist/utils/storage-maintenance.js.map +1 -1
  236. package/dist/utils/thread-lock.js +96 -92
  237. package/dist/utils/thread-lock.js.map +1 -1
  238. package/dist/utils/token-estimator.js +12 -12
  239. package/dist/utils/token-estimator.js.map +1 -1
  240. package/dist/utils/update-check.d.ts +1 -1
  241. package/dist/utils/update-check.js +341 -259
  242. package/dist/utils/update-check.js.map +1 -1
  243. package/dist/voice/stt-registry.js +131 -113
  244. package/dist/voice/stt-registry.js.map +1 -1
  245. package/package.json +11 -11
  246. package/dist/acp.js.map +0 -1
  247. package/dist/auth/index.js.map +0 -1
  248. package/dist/auth/types.js.map +0 -1
  249. package/dist/evals/index.js.map +0 -1
  250. package/dist/evals/scorers/index.js.map +0 -1
  251. package/dist/headless/index.js.map +0 -1
  252. package/dist/hooks/index.js.map +0 -1
  253. package/dist/lsp/index.js.map +0 -1
  254. package/dist/mcp/index.js.map +0 -1
  255. package/dist/mcp/types.js.map +0 -1
  256. package/dist/onboarding/index.js.map +0 -1
  257. package/dist/plugins/types.js.map +0 -1
  258. package/dist/tools/index.js.map +0 -1
@@ -1,302 +1,364 @@
1
- import { execFile, execSync } from "node:child_process";
2
- import { createHash } from "node:crypto";
3
- import fs from "node:fs";
4
- import os from "node:os";
5
- import path from "node:path";
6
1
  import { DEFAULT_CONFIG_DIR } from "../constants.js";
2
+ import { createHash } from "crypto";
3
+ import fs from "fs";
4
+ import os from "os";
5
+ import path from "path";
6
+ import { execFile, execSync } from "child_process";
7
+ //#region src/utils/project.ts
8
+ /**
9
+ * Project detection utilities
10
+ *
11
+ * Detects project identity from git repo or filesystem path.
12
+ * Handles git worktrees by finding the main repository.
13
+ */
14
+ /**
15
+ * Run a git command and return stdout, or undefined if it fails
16
+ */
7
17
  function git(args, cwd) {
8
- try {
9
- return execSync(`git ${args}`, {
10
- cwd,
11
- encoding: "utf-8",
12
- stdio: ["pipe", "pipe", "pipe"]
13
- }).trim();
14
- } catch {
15
- return void 0;
16
- }
18
+ try {
19
+ return execSync(`git ${args}`, {
20
+ cwd,
21
+ encoding: "utf-8",
22
+ stdio: [
23
+ "pipe",
24
+ "pipe",
25
+ "pipe"
26
+ ]
27
+ }).trim();
28
+ } catch {
29
+ return;
30
+ }
17
31
  }
32
+ /**
33
+ * Slugify a string for use in IDs
34
+ */
18
35
  function slugify(str) {
19
- return str.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
36
+ return str.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
20
37
  }
38
+ /**
39
+ * Create a short hash of a string
40
+ */
21
41
  function shortHash(str) {
22
- return createHash("sha256").update(str).digest("hex").slice(0, 12);
42
+ return createHash("sha256").update(str).digest("hex").slice(0, 12);
23
43
  }
44
+ /**
45
+ * Normalize a git URL to a canonical form for comparison
46
+ * - Removes .git suffix
47
+ * - Converts SSH to HTTPS format for consistency
48
+ * - Lowercases
49
+ */
24
50
  function normalizeGitUrl(url) {
25
- return url.replace(/\.git$/, "").replace(/^git@([^:]+):/, "https://$1/").replace(/^ssh:\/\/git@/, "https://").toLowerCase();
51
+ return url.replace(/\.git$/, "").replace(/^git@([^:]+):/, "https://$1/").replace(/^ssh:\/\/git@/, "https://").toLowerCase();
26
52
  }
53
+ /**
54
+ * Detect project info from a directory path
55
+ */
27
56
  function detectProject(projectPath) {
28
- const absolutePath = path.resolve(projectPath);
29
- const gitDir = git("rev-parse --git-dir", absolutePath);
30
- const isGitRepo = gitDir !== void 0;
31
- let rootPath = absolutePath;
32
- let gitUrl;
33
- let gitBranch;
34
- let isWorktree = false;
35
- let mainRepoPath;
36
- if (isGitRepo) {
37
- rootPath = git("rev-parse --show-toplevel", absolutePath) || absolutePath;
38
- const commonDir = git("rev-parse --git-common-dir", absolutePath);
39
- if (commonDir && commonDir !== ".git" && commonDir !== gitDir) {
40
- isWorktree = true;
41
- mainRepoPath = path.dirname(path.resolve(rootPath, commonDir));
42
- }
43
- gitUrl = git("remote get-url origin", absolutePath);
44
- if (!gitUrl) {
45
- const remotes = git("remote", absolutePath);
46
- if (remotes) {
47
- const firstRemote = remotes.split("\n")[0];
48
- if (firstRemote) {
49
- gitUrl = git(`remote get-url ${firstRemote}`, absolutePath);
50
- }
51
- }
52
- }
53
- gitBranch = git("rev-parse --abbrev-ref HEAD", absolutePath);
54
- }
55
- let resourceIdSource;
56
- if (gitUrl) {
57
- resourceIdSource = normalizeGitUrl(gitUrl);
58
- } else if (mainRepoPath) {
59
- resourceIdSource = mainRepoPath;
60
- } else {
61
- resourceIdSource = rootPath;
62
- }
63
- const baseName = gitUrl ? gitUrl.split("/").pop()?.replace(/\.git$/, "") || "project" : path.basename(rootPath);
64
- const resourceId = `${slugify(baseName)}-${shortHash(resourceIdSource)}`;
65
- return {
66
- resourceId,
67
- name: baseName,
68
- rootPath,
69
- gitUrl,
70
- gitBranch,
71
- isWorktree,
72
- mainRepoPath
73
- };
57
+ const absolutePath = path.resolve(projectPath);
58
+ const gitDir = git("rev-parse --git-dir", absolutePath);
59
+ const isGitRepo = gitDir !== void 0;
60
+ let rootPath = absolutePath;
61
+ let gitUrl;
62
+ let gitBranch;
63
+ let isWorktree = false;
64
+ let mainRepoPath;
65
+ if (isGitRepo) {
66
+ rootPath = git("rev-parse --show-toplevel", absolutePath) || absolutePath;
67
+ const commonDir = git("rev-parse --git-common-dir", absolutePath);
68
+ if (commonDir && commonDir !== ".git" && commonDir !== gitDir) {
69
+ isWorktree = true;
70
+ mainRepoPath = path.dirname(path.resolve(rootPath, commonDir));
71
+ }
72
+ gitUrl = git("remote get-url origin", absolutePath);
73
+ if (!gitUrl) {
74
+ const remotes = git("remote", absolutePath);
75
+ if (remotes) {
76
+ const firstRemote = remotes.split("\n")[0];
77
+ if (firstRemote) gitUrl = git(`remote get-url ${firstRemote}`, absolutePath);
78
+ }
79
+ }
80
+ gitBranch = git("rev-parse --abbrev-ref HEAD", absolutePath);
81
+ }
82
+ let resourceIdSource;
83
+ if (gitUrl) resourceIdSource = normalizeGitUrl(gitUrl);
84
+ else if (mainRepoPath) resourceIdSource = mainRepoPath;
85
+ else resourceIdSource = rootPath;
86
+ const baseName = gitUrl ? gitUrl.split("/").pop()?.replace(/\.git$/, "") || "project" : path.basename(rootPath);
87
+ return {
88
+ resourceId: `${slugify(baseName)}-${shortHash(resourceIdSource)}`,
89
+ name: baseName,
90
+ rootPath,
91
+ gitUrl,
92
+ gitBranch,
93
+ isWorktree,
94
+ mainRepoPath
95
+ };
74
96
  }
97
+ /**
98
+ * Get the current git branch for a given directory.
99
+ * Lightweight alternative to detectProject() for refreshing just the branch.
100
+ */
75
101
  function getCurrentGitBranch(cwd) {
76
- return git("rev-parse --abbrev-ref HEAD", cwd);
102
+ return git("rev-parse --abbrev-ref HEAD", cwd);
77
103
  }
104
+ /**
105
+ * Async version of getCurrentGitBranch — avoids blocking the event loop
106
+ * with execSync. Falls back to undefined on any failure.
107
+ */
78
108
  function getCurrentGitBranchAsync(cwd) {
79
- return new Promise((resolve) => {
80
- execFile("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd, encoding: "utf-8" }, (err, stdout) => {
81
- if (err) {
82
- resolve(void 0);
83
- return;
84
- }
85
- const branch = stdout.trim();
86
- resolve(branch || void 0);
87
- });
88
- });
109
+ return new Promise((resolve) => {
110
+ execFile("git", [
111
+ "rev-parse",
112
+ "--abbrev-ref",
113
+ "HEAD"
114
+ ], {
115
+ cwd,
116
+ encoding: "utf-8"
117
+ }, (err, stdout) => {
118
+ if (err) {
119
+ resolve(void 0);
120
+ return;
121
+ }
122
+ resolve(stdout.trim() || void 0);
123
+ });
124
+ });
89
125
  }
126
+ /**
127
+ * Get the application data directory for mastracode
128
+ * - macOS: ~/Library/Application Support/mastracode
129
+ * - Linux: ~/.local/share/mastracode
130
+ * - Windows: %APPDATA%/mastracode
131
+ */
90
132
  function getAppDataDir() {
91
- if (process.env.MASTRA_APP_DATA_DIR) {
92
- fs.mkdirSync(process.env.MASTRA_APP_DATA_DIR, { recursive: true });
93
- return process.env.MASTRA_APP_DATA_DIR;
94
- }
95
- const platform = os.platform();
96
- let baseDir;
97
- if (platform === "darwin") {
98
- baseDir = path.join(os.homedir(), "Library", "Application Support");
99
- } else if (platform === "win32") {
100
- baseDir = process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming");
101
- } else {
102
- baseDir = process.env.XDG_DATA_HOME || path.join(os.homedir(), ".local", "share");
103
- }
104
- const appDir = path.join(baseDir, "mastracode");
105
- if (!fs.existsSync(appDir)) {
106
- fs.mkdirSync(appDir, { recursive: true });
107
- }
108
- return appDir;
133
+ if (process.env.MASTRA_APP_DATA_DIR) {
134
+ fs.mkdirSync(process.env.MASTRA_APP_DATA_DIR, { recursive: true });
135
+ return process.env.MASTRA_APP_DATA_DIR;
136
+ }
137
+ const platform = os.platform();
138
+ let baseDir;
139
+ if (platform === "darwin") baseDir = path.join(os.homedir(), "Library", "Application Support");
140
+ else if (platform === "win32") baseDir = process.env.APPDATA || path.join(os.homedir(), "AppData", "Roaming");
141
+ else baseDir = process.env.XDG_DATA_HOME || path.join(os.homedir(), ".local", "share");
142
+ const appDir = path.join(baseDir, "mastracode");
143
+ if (!fs.existsSync(appDir)) fs.mkdirSync(appDir, { recursive: true });
144
+ return appDir;
109
145
  }
146
+ /**
147
+ * Get the database path for mastracode
148
+ * Can be overridden with the MASTRA_DB_PATH environment variable for debugging.
149
+ */
110
150
  function getDatabasePath() {
111
- if (process.env.MASTRA_DB_PATH) {
112
- return process.env.MASTRA_DB_PATH;
113
- }
114
- return path.join(getAppDataDir(), "mastra.db");
151
+ if (process.env.MASTRA_DB_PATH) return process.env.MASTRA_DB_PATH;
152
+ return path.join(getAppDataDir(), "mastra.db");
115
153
  }
154
+ /**
155
+ * Get the vector database path for mastracode.
156
+ * Separate from the main DB to avoid bloating it with embedding data.
157
+ */
116
158
  function getVectorDatabasePath() {
117
- return path.join(getAppDataDir(), "mastra-vectors.db");
159
+ return path.join(getAppDataDir(), "mastra-vectors.db");
118
160
  }
161
+ /**
162
+ * Get the observability DuckDB database path for mastracode.
163
+ * Separate from the main DB — DuckDB is used for OLAP-style trace/score/feedback queries.
164
+ * Can be overridden with the MASTRA_OBSERVABILITY_DB_PATH environment variable.
165
+ */
119
166
  function getObservabilityDatabasePath() {
120
- if (process.env.MASTRA_OBSERVABILITY_DB_PATH) {
121
- return process.env.MASTRA_OBSERVABILITY_DB_PATH;
122
- }
123
- return path.join(getAppDataDir(), "observability.duckdb");
167
+ if (process.env.MASTRA_OBSERVABILITY_DB_PATH) return process.env.MASTRA_OBSERVABILITY_DB_PATH;
168
+ return path.join(getAppDataDir(), "observability.duckdb");
124
169
  }
170
+ /**
171
+ * Get the resolved storage configuration.
172
+ *
173
+ * Priority (highest to lowest):
174
+ * 1. Environment variables: MASTRA_STORAGE_BACKEND + backend-specific vars
175
+ * 2. Global settings (from /settings): settings.storage
176
+ * 3. Legacy config files: .mastracode/database.json (LibSQL only)
177
+ * 4. Local file database (LibSQL default)
178
+ *
179
+ * For PG, the env vars are:
180
+ * MASTRA_STORAGE_BACKEND=pg
181
+ * MASTRA_PG_CONNECTION_STRING or MASTRA_PG_HOST/PORT/DATABASE/USER/PASSWORD
182
+ * MASTRA_PG_SCHEMA_NAME (optional)
183
+ *
184
+ * For LibSQL, the legacy env vars still work:
185
+ * MASTRA_DB_URL + MASTRA_DB_AUTH_TOKEN
186
+ */
125
187
  function getStorageConfig(projectDir, storageSettings, configDirName = DEFAULT_CONFIG_DIR) {
126
- const envBackend = process.env.MASTRA_STORAGE_BACKEND;
127
- if (envBackend === "pg") {
128
- return resolvePgFromEnv();
129
- }
130
- if (envBackend === "libsql" || process.env.MASTRA_DB_URL) {
131
- return resolveLibSQLFromEnv();
132
- }
133
- if (storageSettings && storageSettings.backend === "pg") {
134
- return resolvePgFromSettings(storageSettings);
135
- }
136
- if (storageSettings && storageSettings.backend === "libsql" && storageSettings.libsql.url) {
137
- return {
138
- backend: "libsql",
139
- url: storageSettings.libsql.url,
140
- authToken: storageSettings.libsql.authToken,
141
- isRemote: !storageSettings.libsql.url.startsWith("file:")
142
- };
143
- }
144
- if (projectDir) {
145
- const projectConfig = loadDatabaseConfig(path.join(projectDir, configDirName, "database.json"));
146
- if (projectConfig) return projectConfig;
147
- }
148
- const globalConfig = loadDatabaseConfig(path.join(os.homedir(), configDirName, "database.json"));
149
- if (globalConfig) return globalConfig;
150
- return {
151
- backend: "libsql",
152
- url: `file:${getDatabasePath()}`,
153
- isRemote: false
154
- };
188
+ const envBackend = process.env.MASTRA_STORAGE_BACKEND;
189
+ if (envBackend === "pg") return resolvePgFromEnv();
190
+ if (envBackend === "libsql" || process.env.MASTRA_DB_URL) return resolveLibSQLFromEnv();
191
+ if (storageSettings && storageSettings.backend === "pg") return resolvePgFromSettings(storageSettings);
192
+ if (storageSettings && storageSettings.backend === "libsql" && storageSettings.libsql.url) return {
193
+ backend: "libsql",
194
+ url: storageSettings.libsql.url,
195
+ authToken: storageSettings.libsql.authToken,
196
+ isRemote: !storageSettings.libsql.url.startsWith("file:")
197
+ };
198
+ if (projectDir) {
199
+ const projectConfig = loadDatabaseConfig(path.join(projectDir, configDirName, "database.json"));
200
+ if (projectConfig) return projectConfig;
201
+ }
202
+ const globalConfig = loadDatabaseConfig(path.join(os.homedir(), configDirName, "database.json"));
203
+ if (globalConfig) return globalConfig;
204
+ return {
205
+ backend: "libsql",
206
+ url: `file:${getDatabasePath()}`,
207
+ isRemote: false
208
+ };
155
209
  }
156
210
  function resolveLibSQLFromEnv() {
157
- const url = process.env.MASTRA_DB_URL;
158
- return {
159
- backend: "libsql",
160
- url,
161
- authToken: process.env.MASTRA_DB_AUTH_TOKEN,
162
- isRemote: !url.startsWith("file:")
163
- };
211
+ const url = process.env.MASTRA_DB_URL;
212
+ return {
213
+ backend: "libsql",
214
+ url,
215
+ authToken: process.env.MASTRA_DB_AUTH_TOKEN,
216
+ isRemote: !url.startsWith("file:")
217
+ };
164
218
  }
165
219
  function resolvePgFromEnv() {
166
- const connectionString = process.env.MASTRA_PG_CONNECTION_STRING;
167
- if (connectionString) {
168
- return {
169
- backend: "pg",
170
- connectionString,
171
- schemaName: process.env.MASTRA_PG_SCHEMA_NAME
172
- };
173
- }
174
- return {
175
- backend: "pg",
176
- host: process.env.MASTRA_PG_HOST,
177
- port: process.env.MASTRA_PG_PORT ? parseInt(process.env.MASTRA_PG_PORT, 10) : void 0,
178
- database: process.env.MASTRA_PG_DATABASE,
179
- user: process.env.MASTRA_PG_USER,
180
- password: process.env.MASTRA_PG_PASSWORD,
181
- schemaName: process.env.MASTRA_PG_SCHEMA_NAME
182
- };
220
+ const connectionString = process.env.MASTRA_PG_CONNECTION_STRING;
221
+ if (connectionString) return {
222
+ backend: "pg",
223
+ connectionString,
224
+ schemaName: process.env.MASTRA_PG_SCHEMA_NAME
225
+ };
226
+ return {
227
+ backend: "pg",
228
+ host: process.env.MASTRA_PG_HOST,
229
+ port: process.env.MASTRA_PG_PORT ? parseInt(process.env.MASTRA_PG_PORT, 10) : void 0,
230
+ database: process.env.MASTRA_PG_DATABASE,
231
+ user: process.env.MASTRA_PG_USER,
232
+ password: process.env.MASTRA_PG_PASSWORD,
233
+ schemaName: process.env.MASTRA_PG_SCHEMA_NAME
234
+ };
183
235
  }
184
236
  function resolvePgFromSettings(settings) {
185
- const pg = settings.pg;
186
- return {
187
- backend: "pg",
188
- connectionString: pg.connectionString,
189
- host: pg.host,
190
- port: pg.port,
191
- database: pg.database,
192
- user: pg.user,
193
- password: pg.password,
194
- schemaName: pg.schemaName,
195
- disableInit: pg.disableInit,
196
- skipDefaultIndexes: pg.skipDefaultIndexes
197
- };
237
+ const pg = settings.pg;
238
+ return {
239
+ backend: "pg",
240
+ connectionString: pg.connectionString,
241
+ host: pg.host,
242
+ port: pg.port,
243
+ database: pg.database,
244
+ user: pg.user,
245
+ password: pg.password,
246
+ schemaName: pg.schemaName,
247
+ disableInit: pg.disableInit,
248
+ skipDefaultIndexes: pg.skipDefaultIndexes
249
+ };
198
250
  }
251
+ /**
252
+ * Load database config from a legacy JSON file.
253
+ * Expected format: { "url": "libsql://...", "authToken": "..." }
254
+ */
199
255
  function loadDatabaseConfig(filePath) {
200
- try {
201
- if (!fs.existsSync(filePath)) return null;
202
- const raw = fs.readFileSync(filePath, "utf-8");
203
- const parsed = JSON.parse(raw);
204
- if (typeof parsed?.url === "string" && parsed.url) {
205
- return {
206
- backend: "libsql",
207
- url: parsed.url,
208
- authToken: typeof parsed.authToken === "string" ? parsed.authToken : void 0,
209
- isRemote: !parsed.url.startsWith("file:")
210
- };
211
- }
212
- return null;
213
- } catch {
214
- return null;
215
- }
256
+ try {
257
+ if (!fs.existsSync(filePath)) return null;
258
+ const raw = fs.readFileSync(filePath, "utf-8");
259
+ const parsed = JSON.parse(raw);
260
+ if (typeof parsed?.url === "string" && parsed.url) return {
261
+ backend: "libsql",
262
+ url: parsed.url,
263
+ authToken: typeof parsed.authToken === "string" ? parsed.authToken : void 0,
264
+ isRemote: !parsed.url.startsWith("file:")
265
+ };
266
+ return null;
267
+ } catch {
268
+ return null;
269
+ }
216
270
  }
271
+ /**
272
+ * Get the current user identity.
273
+ *
274
+ * Priority:
275
+ * 1. MASTRA_USER_ID environment variable
276
+ * 2. git config user.email (from project dir or global)
277
+ * 3. OS username as fallback
278
+ */
217
279
  function getUserId(projectDir) {
218
- if (process.env.MASTRA_USER_ID) {
219
- return process.env.MASTRA_USER_ID;
220
- }
221
- const cwd = projectDir || process.cwd();
222
- const email = git("config user.email", cwd);
223
- if (email) {
224
- return email;
225
- }
226
- return os.userInfo().username || "unknown";
280
+ if (process.env.MASTRA_USER_ID) return process.env.MASTRA_USER_ID;
281
+ const email = git("config user.email", projectDir || process.cwd());
282
+ if (email) return email;
283
+ return os.userInfo().username || "unknown";
227
284
  }
285
+ /**
286
+ * Get the current user's display name.
287
+ *
288
+ * Priority:
289
+ * 1. git config user.name
290
+ * 2. OS username as fallback
291
+ */
228
292
  function getUserName(projectDir) {
229
- const cwd = projectDir || process.cwd();
230
- const name = git("config user.name", cwd);
231
- if (name) {
232
- return name;
233
- }
234
- return os.userInfo().username || "unknown";
293
+ const name = git("config user.name", projectDir || process.cwd());
294
+ if (name) return name;
295
+ return os.userInfo().username || "unknown";
235
296
  }
297
+ /**
298
+ * Get the configured observational memory scope.
299
+ *
300
+ * Priority:
301
+ * 1. MASTRA_OM_SCOPE environment variable ("thread" or "resource")
302
+ * 2. Project config: .mastracode/database.json → omScope
303
+ * 3. Global config: ~/.mastracode/database.json → omScope
304
+ * 4. Default: "thread"
305
+ */
236
306
  function getOmScope(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
237
- const envScope = process.env.MASTRA_OM_SCOPE;
238
- if (envScope === "thread" || envScope === "resource") {
239
- return envScope;
240
- }
241
- if (projectDir) {
242
- const scope2 = loadOmScopeFromConfig(path.join(projectDir, configDirName, "database.json"));
243
- if (scope2) return scope2;
244
- }
245
- const scope = loadOmScopeFromConfig(path.join(os.homedir(), configDirName, "database.json"));
246
- if (scope) return scope;
247
- return "thread";
307
+ const envScope = process.env.MASTRA_OM_SCOPE;
308
+ if (envScope === "thread" || envScope === "resource") return envScope;
309
+ if (projectDir) {
310
+ const scope = loadOmScopeFromConfig(path.join(projectDir, configDirName, "database.json"));
311
+ if (scope) return scope;
312
+ }
313
+ const scope = loadOmScopeFromConfig(path.join(os.homedir(), configDirName, "database.json"));
314
+ if (scope) return scope;
315
+ return "thread";
248
316
  }
249
317
  function loadOmScopeFromConfig(filePath) {
250
- try {
251
- if (!fs.existsSync(filePath)) return null;
252
- const raw = fs.readFileSync(filePath, "utf-8");
253
- const parsed = JSON.parse(raw);
254
- if (parsed?.omScope === "thread" || parsed?.omScope === "resource") {
255
- return parsed.omScope;
256
- }
257
- return null;
258
- } catch {
259
- return null;
260
- }
318
+ try {
319
+ if (!fs.existsSync(filePath)) return null;
320
+ const raw = fs.readFileSync(filePath, "utf-8");
321
+ const parsed = JSON.parse(raw);
322
+ if (parsed?.omScope === "thread" || parsed?.omScope === "resource") return parsed.omScope;
323
+ return null;
324
+ } catch {
325
+ return null;
326
+ }
261
327
  }
328
+ /**
329
+ * Get an explicit resource ID override, if configured.
330
+ *
331
+ * Resource IDs act as shared tags — two users who set the same resourceId
332
+ * will share threads and observations for that resource.
333
+ *
334
+ * Priority:
335
+ * 1. MASTRA_RESOURCE_ID environment variable
336
+ * 2. Project config: .mastracode/database.json → resourceId
337
+ * 3. Global config: ~/.mastracode/database.json → resourceId
338
+ * 4. null (use auto-detected value)
339
+ */
262
340
  function getResourceIdOverride(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
263
- if (process.env.MASTRA_RESOURCE_ID) {
264
- return process.env.MASTRA_RESOURCE_ID;
265
- }
266
- if (projectDir) {
267
- const rid2 = loadStringField(path.join(projectDir, configDirName, "database.json"), "resourceId");
268
- if (rid2) return rid2;
269
- }
270
- const rid = loadStringField(path.join(os.homedir(), configDirName, "database.json"), "resourceId");
271
- if (rid) return rid;
272
- return null;
341
+ if (process.env.MASTRA_RESOURCE_ID) return process.env.MASTRA_RESOURCE_ID;
342
+ if (projectDir) {
343
+ const rid = loadStringField(path.join(projectDir, configDirName, "database.json"), "resourceId");
344
+ if (rid) return rid;
345
+ }
346
+ const rid = loadStringField(path.join(os.homedir(), configDirName, "database.json"), "resourceId");
347
+ if (rid) return rid;
348
+ return null;
273
349
  }
274
350
  function loadStringField(filePath, field) {
275
- try {
276
- if (!fs.existsSync(filePath)) return null;
277
- const raw = fs.readFileSync(filePath, "utf-8");
278
- const parsed = JSON.parse(raw);
279
- const value = parsed?.[field];
280
- if (typeof value === "string" && value) {
281
- return value;
282
- }
283
- return null;
284
- } catch {
285
- return null;
286
- }
351
+ try {
352
+ if (!fs.existsSync(filePath)) return null;
353
+ const raw = fs.readFileSync(filePath, "utf-8");
354
+ const value = JSON.parse(raw)?.[field];
355
+ if (typeof value === "string" && value) return value;
356
+ return null;
357
+ } catch {
358
+ return null;
359
+ }
287
360
  }
288
- export {
289
- detectProject,
290
- getAppDataDir,
291
- getCurrentGitBranch,
292
- getCurrentGitBranchAsync,
293
- getDatabasePath,
294
- getObservabilityDatabasePath,
295
- getOmScope,
296
- getResourceIdOverride,
297
- getStorageConfig,
298
- getUserId,
299
- getUserName,
300
- getVectorDatabasePath
301
- };
361
+ //#endregion
362
+ export { detectProject, getAppDataDir, getCurrentGitBranch, getCurrentGitBranchAsync, getDatabasePath, getObservabilityDatabasePath, getOmScope, getResourceIdOverride, getStorageConfig, getUserId, getUserName, getVectorDatabasePath };
363
+
302
364
  //# sourceMappingURL=project.js.map