@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
package/dist/analytics.js CHANGED
@@ -1,152 +1,163 @@
1
- import { randomUUID } from "node:crypto";
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
- import os from "node:os";
4
- import path from "node:path";
1
+ import { randomUUID } from "crypto";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
3
+ import os from "os";
4
+ import path from "path";
5
5
  import { PostHog } from "posthog-node";
6
+ //#region src/analytics.ts
6
7
  const POSTHOG_API_KEY = "phc_SBLpZVAB6jmHOct9CABq3PF0Yn5FU3G2FgT4xUr2XrT";
7
8
  const POSTHOG_HOST = "https://us.posthog.com";
8
9
  const MASTRA_SOURCE = "mastracode";
9
- const TRUTHY_DISABLED_VALUES = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
10
+ const TRUTHY_DISABLED_VALUES = /* @__PURE__ */ new Set([
11
+ "1",
12
+ "true",
13
+ "yes",
14
+ "on"
15
+ ]);
10
16
  const ANALYTICS_CONFIG_PATH = path.join(os.homedir(), ".mastracode", "analytics.json");
11
17
  function createMastraAnalyticsDistinctId() {
12
- return `mastra-${randomUUID()}`;
18
+ return `mastra-${randomUUID()}`;
13
19
  }
14
20
  function isHostnameDerivedDistinctId(distinctId, hostname = os.hostname()) {
15
- return distinctId === `mastra-${hostname}`;
21
+ return distinctId === `mastra-${hostname}`;
16
22
  }
17
23
  function isValidMastraAnalyticsDistinctId(distinctId) {
18
- return /^mastra-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(distinctId);
24
+ return /^mastra-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(distinctId);
19
25
  }
20
26
  function writeAnalyticsConfig(distinctId, configPath = ANALYTICS_CONFIG_PATH) {
21
- try {
22
- mkdirSync(path.dirname(configPath), { recursive: true });
23
- writeFileSync(configPath, JSON.stringify({ distinctId }));
24
- } catch {
25
- }
27
+ try {
28
+ mkdirSync(path.dirname(configPath), { recursive: true });
29
+ writeFileSync(configPath, JSON.stringify({ distinctId }));
30
+ } catch {}
26
31
  }
27
32
  function getMastraAnalyticsDistinctId(configPath = ANALYTICS_CONFIG_PATH) {
28
- try {
29
- if (existsSync(configPath)) {
30
- const config = JSON.parse(readFileSync(configPath, "utf-8"));
31
- if (config.distinctId && isValidMastraAnalyticsDistinctId(config.distinctId) && !isHostnameDerivedDistinctId(config.distinctId)) {
32
- return config.distinctId;
33
- }
34
- }
35
- } catch {
36
- }
37
- const distinctId = createMastraAnalyticsDistinctId();
38
- writeAnalyticsConfig(distinctId, configPath);
39
- return distinctId;
33
+ try {
34
+ if (existsSync(configPath)) {
35
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
36
+ if (config.distinctId && isValidMastraAnalyticsDistinctId(config.distinctId) && !isHostnameDerivedDistinctId(config.distinctId)) return config.distinctId;
37
+ }
38
+ } catch {}
39
+ const distinctId = createMastraAnalyticsDistinctId();
40
+ writeAnalyticsConfig(distinctId, configPath);
41
+ return distinctId;
40
42
  }
41
43
  function isAnalyticsDebugEnabled() {
42
- return TRUTHY_DISABLED_VALUES.has(process.env.MASTRACODE_ANALYTICS_DEBUG?.trim().toLowerCase() ?? "");
44
+ return TRUTHY_DISABLED_VALUES.has(process.env.MASTRACODE_ANALYTICS_DEBUG?.trim().toLowerCase() ?? "");
43
45
  }
44
46
  function debugAnalytics(message, properties) {
45
- if (!isAnalyticsDebugEnabled()) {
46
- return;
47
- }
48
- const suffix = properties ? ` ${JSON.stringify(properties)}` : "";
49
- process.stderr.write(`[mastracode analytics] ${message}${suffix}
50
- `);
51
- }
52
- class NoopMastraCodeAnalytics {
53
- capture(event) {
54
- debugAnalytics("capture skipped: telemetry disabled", { event });
55
- }
56
- trackCommand(command) {
57
- debugAnalytics("command skipped: telemetry disabled", { command });
58
- }
59
- trackInteractivePrompt(promptType) {
60
- debugAnalytics("interactive prompt skipped: telemetry disabled", { promptType });
61
- }
62
- async shutdown() {
63
- debugAnalytics("shutdown skipped: telemetry disabled");
64
- }
65
- isEnabled() {
66
- return false;
67
- }
68
- }
69
- class PostHogMastraCodeAnalytics {
70
- client;
71
- distinctId;
72
- sessionId = randomUUID();
73
- version;
74
- constructor({ version, apiKey = POSTHOG_API_KEY, host = POSTHOG_HOST }) {
75
- this.version = version;
76
- this.distinctId = getMastraAnalyticsDistinctId();
77
- this.client = new PostHog(apiKey, {
78
- host,
79
- flushAt: 1,
80
- flushInterval: 0,
81
- disableGeoip: false
82
- });
83
- this.client.register({ mastraSource: MASTRA_SOURCE });
84
- debugAnalytics("enabled", { host, distinctId: this.distinctId, version });
85
- }
86
- capture(event, properties) {
87
- try {
88
- const eventProperties = {
89
- ...this.getBaseProperties(),
90
- ...properties
91
- };
92
- debugAnalytics("capture", { event, properties: eventProperties });
93
- this.client.capture({
94
- distinctId: this.distinctId,
95
- event,
96
- properties: eventProperties
97
- });
98
- } catch (error) {
99
- debugAnalytics("capture failed", { event, error: error instanceof Error ? error.message : String(error) });
100
- }
101
- }
102
- trackCommand(command, properties) {
103
- this.capture("mastracode_command_used", { command, ...properties });
104
- }
105
- trackInteractivePrompt(promptType, properties) {
106
- this.capture("mastracode_interactive_prompt_shown", { promptType, ...properties });
107
- }
108
- async shutdown() {
109
- try {
110
- debugAnalytics("shutdown start");
111
- await this.client.shutdown();
112
- debugAnalytics("shutdown complete");
113
- } catch (error) {
114
- debugAnalytics("shutdown failed", { error: error instanceof Error ? error.message : String(error) });
115
- }
116
- }
117
- isEnabled() {
118
- return true;
119
- }
120
- getBaseProperties() {
121
- return {
122
- mastraSource: MASTRA_SOURCE,
123
- sessionId: this.sessionId,
124
- version: this.version,
125
- os: process.platform,
126
- osVersion: os.release(),
127
- nodeVersion: process.version,
128
- platform: process.arch,
129
- machineId: os.hostname()
130
- };
131
- }
47
+ if (!isAnalyticsDebugEnabled()) return;
48
+ const suffix = properties ? ` ${JSON.stringify(properties)}` : "";
49
+ process.stderr.write(`[mastracode analytics] ${message}${suffix}\n`);
132
50
  }
51
+ var NoopMastraCodeAnalytics = class {
52
+ capture(event) {
53
+ debugAnalytics("capture skipped: telemetry disabled", { event });
54
+ }
55
+ trackCommand(command) {
56
+ debugAnalytics("command skipped: telemetry disabled", { command });
57
+ }
58
+ trackInteractivePrompt(promptType) {
59
+ debugAnalytics("interactive prompt skipped: telemetry disabled", { promptType });
60
+ }
61
+ async shutdown() {
62
+ debugAnalytics("shutdown skipped: telemetry disabled");
63
+ }
64
+ isEnabled() {
65
+ return false;
66
+ }
67
+ };
68
+ var PostHogMastraCodeAnalytics = class {
69
+ client;
70
+ distinctId;
71
+ sessionId = randomUUID();
72
+ version;
73
+ constructor({ version, apiKey = POSTHOG_API_KEY, host = POSTHOG_HOST }) {
74
+ this.version = version;
75
+ this.distinctId = getMastraAnalyticsDistinctId();
76
+ this.client = new PostHog(apiKey, {
77
+ host,
78
+ flushAt: 1,
79
+ flushInterval: 0,
80
+ disableGeoip: false
81
+ });
82
+ this.client.register({ mastraSource: MASTRA_SOURCE });
83
+ debugAnalytics("enabled", {
84
+ host,
85
+ distinctId: this.distinctId,
86
+ version
87
+ });
88
+ }
89
+ capture(event, properties) {
90
+ try {
91
+ const eventProperties = {
92
+ ...this.getBaseProperties(),
93
+ ...properties
94
+ };
95
+ debugAnalytics("capture", {
96
+ event,
97
+ properties: eventProperties
98
+ });
99
+ this.client.capture({
100
+ distinctId: this.distinctId,
101
+ event,
102
+ properties: eventProperties
103
+ });
104
+ } catch (error) {
105
+ debugAnalytics("capture failed", {
106
+ event,
107
+ error: error instanceof Error ? error.message : String(error)
108
+ });
109
+ }
110
+ }
111
+ trackCommand(command, properties) {
112
+ this.capture("mastracode_command_used", {
113
+ command,
114
+ ...properties
115
+ });
116
+ }
117
+ trackInteractivePrompt(promptType, properties) {
118
+ this.capture("mastracode_interactive_prompt_shown", {
119
+ promptType,
120
+ ...properties
121
+ });
122
+ }
123
+ async shutdown() {
124
+ try {
125
+ debugAnalytics("shutdown start");
126
+ await this.client.shutdown();
127
+ debugAnalytics("shutdown complete");
128
+ } catch (error) {
129
+ debugAnalytics("shutdown failed", { error: error instanceof Error ? error.message : String(error) });
130
+ }
131
+ }
132
+ isEnabled() {
133
+ return true;
134
+ }
135
+ getBaseProperties() {
136
+ return {
137
+ mastraSource: MASTRA_SOURCE,
138
+ sessionId: this.sessionId,
139
+ version: this.version,
140
+ os: process.platform,
141
+ osVersion: os.release(),
142
+ nodeVersion: process.version,
143
+ platform: process.arch,
144
+ machineId: os.hostname()
145
+ };
146
+ }
147
+ };
133
148
  function isTelemetryDisabled(env = process.env) {
134
- const value = env.MASTRA_TELEMETRY_DISABLED;
135
- if (!value) {
136
- return false;
137
- }
138
- return TRUTHY_DISABLED_VALUES.has(value.trim().toLowerCase());
149
+ const value = env.MASTRA_TELEMETRY_DISABLED;
150
+ if (!value) return false;
151
+ return TRUTHY_DISABLED_VALUES.has(value.trim().toLowerCase());
139
152
  }
140
153
  function createMastraCodeAnalytics(options) {
141
- if (isTelemetryDisabled()) {
142
- debugAnalytics("disabled by MASTRA_TELEMETRY_DISABLED", { value: process.env.MASTRA_TELEMETRY_DISABLED });
143
- return new NoopMastraCodeAnalytics();
144
- }
145
- return new PostHogMastraCodeAnalytics(options);
154
+ if (isTelemetryDisabled()) {
155
+ debugAnalytics("disabled by MASTRA_TELEMETRY_DISABLED", { value: process.env.MASTRA_TELEMETRY_DISABLED });
156
+ return new NoopMastraCodeAnalytics();
157
+ }
158
+ return new PostHogMastraCodeAnalytics(options);
146
159
  }
147
- export {
148
- createMastraCodeAnalytics,
149
- getMastraAnalyticsDistinctId,
150
- isTelemetryDisabled
151
- };
160
+ //#endregion
161
+ export { createMastraCodeAnalytics, getMastraAnalyticsDistinctId, isTelemetryDisabled };
162
+
152
163
  //# sourceMappingURL=analytics.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/analytics.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { PostHog } from 'posthog-node';\n\nconst POSTHOG_API_KEY = 'phc_SBLpZVAB6jmHOct9CABq3PF0Yn5FU3G2FgT4xUr2XrT';\nconst POSTHOG_HOST = 'https://us.posthog.com';\nconst MASTRA_SOURCE = 'mastracode';\nconst TRUTHY_DISABLED_VALUES = new Set(['1', 'true', 'yes', 'on']);\nconst ANALYTICS_CONFIG_PATH = path.join(os.homedir(), '.mastracode', 'analytics.json');\n\ninterface AnalyticsConfig {\n distinctId?: string;\n}\n\nfunction createMastraAnalyticsDistinctId(): string {\n return `mastra-${randomUUID()}`;\n}\n\nfunction isHostnameDerivedDistinctId(distinctId: string, hostname = os.hostname()): boolean {\n return distinctId === `mastra-${hostname}`;\n}\n\nfunction isValidMastraAnalyticsDistinctId(distinctId: string): boolean {\n return /^mastra-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(distinctId);\n}\n\nfunction writeAnalyticsConfig(distinctId: string, configPath = ANALYTICS_CONFIG_PATH): void {\n try {\n mkdirSync(path.dirname(configPath), { recursive: true });\n writeFileSync(configPath, JSON.stringify({ distinctId }));\n } catch {\n // swallow analytics persistence errors\n }\n}\n\nexport function getMastraAnalyticsDistinctId(configPath = ANALYTICS_CONFIG_PATH): string {\n try {\n if (existsSync(configPath)) {\n const config = JSON.parse(readFileSync(configPath, 'utf-8')) as AnalyticsConfig;\n if (\n config.distinctId &&\n isValidMastraAnalyticsDistinctId(config.distinctId) &&\n !isHostnameDerivedDistinctId(config.distinctId)\n ) {\n return config.distinctId;\n }\n }\n } catch {\n // regenerate below\n }\n\n const distinctId = createMastraAnalyticsDistinctId();\n writeAnalyticsConfig(distinctId, configPath);\n return distinctId;\n}\n\nfunction isAnalyticsDebugEnabled(): boolean {\n return TRUTHY_DISABLED_VALUES.has(process.env.MASTRACODE_ANALYTICS_DEBUG?.trim().toLowerCase() ?? '');\n}\n\nfunction debugAnalytics(message: string, properties?: Record<string, unknown>): void {\n if (!isAnalyticsDebugEnabled()) {\n return;\n }\n\n const suffix = properties ? ` ${JSON.stringify(properties)}` : '';\n process.stderr.write(`[mastracode analytics] ${message}${suffix}\\n`);\n}\n\nexport type MastraCodeAnalyticsEvent =\n | 'mastracode_session_started'\n | 'mastracode_prompt_submitted'\n | 'mastracode_thread_changed'\n | 'mastracode_model_changed'\n | 'mastracode_command_used'\n | 'mastracode_interactive_prompt_shown';\n\nexport interface MastraCodeAnalytics {\n capture(event: MastraCodeAnalyticsEvent, properties?: Record<string, unknown>): void;\n trackCommand(command: string, properties?: Record<string, unknown>): void;\n trackInteractivePrompt(promptType: string, properties?: Record<string, unknown>): void;\n shutdown(): Promise<void>;\n isEnabled(): boolean;\n}\n\ninterface MastraCodeAnalyticsOptions {\n version: string;\n host?: string;\n apiKey?: string;\n}\n\nclass NoopMastraCodeAnalytics implements MastraCodeAnalytics {\n capture(event: MastraCodeAnalyticsEvent): void {\n debugAnalytics('capture skipped: telemetry disabled', { event });\n }\n trackCommand(command: string): void {\n debugAnalytics('command skipped: telemetry disabled', { command });\n }\n trackInteractivePrompt(promptType: string): void {\n debugAnalytics('interactive prompt skipped: telemetry disabled', { promptType });\n }\n async shutdown(): Promise<void> {\n debugAnalytics('shutdown skipped: telemetry disabled');\n }\n isEnabled(): boolean {\n return false;\n }\n}\n\nclass PostHogMastraCodeAnalytics implements MastraCodeAnalytics {\n private readonly client: PostHog;\n private readonly distinctId: string;\n private readonly sessionId = randomUUID();\n private readonly version: string;\n\n constructor({ version, apiKey = POSTHOG_API_KEY, host = POSTHOG_HOST }: MastraCodeAnalyticsOptions) {\n this.version = version;\n this.distinctId = getMastraAnalyticsDistinctId();\n this.client = new PostHog(apiKey, {\n host,\n flushAt: 1,\n flushInterval: 0,\n disableGeoip: false,\n });\n this.client.register({ mastraSource: MASTRA_SOURCE });\n debugAnalytics('enabled', { host, distinctId: this.distinctId, version });\n }\n\n capture(event: MastraCodeAnalyticsEvent, properties?: Record<string, unknown>): void {\n try {\n const eventProperties = {\n ...this.getBaseProperties(),\n ...properties,\n };\n debugAnalytics('capture', { event, properties: eventProperties });\n this.client.capture({\n distinctId: this.distinctId,\n event,\n properties: eventProperties,\n });\n } catch (error) {\n debugAnalytics('capture failed', { event, error: error instanceof Error ? error.message : String(error) });\n // swallow analytics errors\n }\n }\n\n trackCommand(command: string, properties?: Record<string, unknown>): void {\n this.capture('mastracode_command_used', { command, ...properties });\n }\n\n trackInteractivePrompt(promptType: string, properties?: Record<string, unknown>): void {\n this.capture('mastracode_interactive_prompt_shown', { promptType, ...properties });\n }\n\n async shutdown(): Promise<void> {\n try {\n debugAnalytics('shutdown start');\n await this.client.shutdown();\n debugAnalytics('shutdown complete');\n } catch (error) {\n debugAnalytics('shutdown failed', { error: error instanceof Error ? error.message : String(error) });\n // swallow analytics errors\n }\n }\n\n isEnabled(): boolean {\n return true;\n }\n\n private getBaseProperties(): Record<string, unknown> {\n return {\n mastraSource: MASTRA_SOURCE,\n sessionId: this.sessionId,\n version: this.version,\n os: process.platform,\n osVersion: os.release(),\n nodeVersion: process.version,\n platform: process.arch,\n machineId: os.hostname(),\n };\n }\n}\n\nexport function isTelemetryDisabled(env: NodeJS.ProcessEnv = process.env): boolean {\n const value = env.MASTRA_TELEMETRY_DISABLED;\n if (!value) {\n return false;\n }\n\n return TRUTHY_DISABLED_VALUES.has(value.trim().toLowerCase());\n}\n\nexport function createMastraCodeAnalytics(options: MastraCodeAnalyticsOptions): MastraCodeAnalytics {\n if (isTelemetryDisabled()) {\n debugAnalytics('disabled by MASTRA_TELEMETRY_DISABLED', { value: process.env.MASTRA_TELEMETRY_DISABLED });\n return new NoopMastraCodeAnalytics();\n }\n\n return new PostHogMastraCodeAnalytics(options);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"analytics.js","names":[],"sources":["../src/analytics.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { PostHog } from 'posthog-node';\n\nconst POSTHOG_API_KEY = 'phc_SBLpZVAB6jmHOct9CABq3PF0Yn5FU3G2FgT4xUr2XrT';\nconst POSTHOG_HOST = 'https://us.posthog.com';\nconst MASTRA_SOURCE = 'mastracode';\nconst TRUTHY_DISABLED_VALUES = new Set(['1', 'true', 'yes', 'on']);\nconst ANALYTICS_CONFIG_PATH = path.join(os.homedir(), '.mastracode', 'analytics.json');\n\ninterface AnalyticsConfig {\n distinctId?: string;\n}\n\nfunction createMastraAnalyticsDistinctId(): string {\n return `mastra-${randomUUID()}`;\n}\n\nfunction isHostnameDerivedDistinctId(distinctId: string, hostname = os.hostname()): boolean {\n return distinctId === `mastra-${hostname}`;\n}\n\nfunction isValidMastraAnalyticsDistinctId(distinctId: string): boolean {\n return /^mastra-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(distinctId);\n}\n\nfunction writeAnalyticsConfig(distinctId: string, configPath = ANALYTICS_CONFIG_PATH): void {\n try {\n mkdirSync(path.dirname(configPath), { recursive: true });\n writeFileSync(configPath, JSON.stringify({ distinctId }));\n } catch {\n // swallow analytics persistence errors\n }\n}\n\nexport function getMastraAnalyticsDistinctId(configPath = ANALYTICS_CONFIG_PATH): string {\n try {\n if (existsSync(configPath)) {\n const config = JSON.parse(readFileSync(configPath, 'utf-8')) as AnalyticsConfig;\n if (\n config.distinctId &&\n isValidMastraAnalyticsDistinctId(config.distinctId) &&\n !isHostnameDerivedDistinctId(config.distinctId)\n ) {\n return config.distinctId;\n }\n }\n } catch {\n // regenerate below\n }\n\n const distinctId = createMastraAnalyticsDistinctId();\n writeAnalyticsConfig(distinctId, configPath);\n return distinctId;\n}\n\nfunction isAnalyticsDebugEnabled(): boolean {\n return TRUTHY_DISABLED_VALUES.has(process.env.MASTRACODE_ANALYTICS_DEBUG?.trim().toLowerCase() ?? '');\n}\n\nfunction debugAnalytics(message: string, properties?: Record<string, unknown>): void {\n if (!isAnalyticsDebugEnabled()) {\n return;\n }\n\n const suffix = properties ? ` ${JSON.stringify(properties)}` : '';\n process.stderr.write(`[mastracode analytics] ${message}${suffix}\\n`);\n}\n\nexport type MastraCodeAnalyticsEvent =\n | 'mastracode_session_started'\n | 'mastracode_prompt_submitted'\n | 'mastracode_thread_changed'\n | 'mastracode_model_changed'\n | 'mastracode_command_used'\n | 'mastracode_interactive_prompt_shown';\n\nexport interface MastraCodeAnalytics {\n capture(event: MastraCodeAnalyticsEvent, properties?: Record<string, unknown>): void;\n trackCommand(command: string, properties?: Record<string, unknown>): void;\n trackInteractivePrompt(promptType: string, properties?: Record<string, unknown>): void;\n shutdown(): Promise<void>;\n isEnabled(): boolean;\n}\n\ninterface MastraCodeAnalyticsOptions {\n version: string;\n host?: string;\n apiKey?: string;\n}\n\nclass NoopMastraCodeAnalytics implements MastraCodeAnalytics {\n capture(event: MastraCodeAnalyticsEvent): void {\n debugAnalytics('capture skipped: telemetry disabled', { event });\n }\n trackCommand(command: string): void {\n debugAnalytics('command skipped: telemetry disabled', { command });\n }\n trackInteractivePrompt(promptType: string): void {\n debugAnalytics('interactive prompt skipped: telemetry disabled', { promptType });\n }\n async shutdown(): Promise<void> {\n debugAnalytics('shutdown skipped: telemetry disabled');\n }\n isEnabled(): boolean {\n return false;\n }\n}\n\nclass PostHogMastraCodeAnalytics implements MastraCodeAnalytics {\n private readonly client: PostHog;\n private readonly distinctId: string;\n private readonly sessionId = randomUUID();\n private readonly version: string;\n\n constructor({ version, apiKey = POSTHOG_API_KEY, host = POSTHOG_HOST }: MastraCodeAnalyticsOptions) {\n this.version = version;\n this.distinctId = getMastraAnalyticsDistinctId();\n this.client = new PostHog(apiKey, {\n host,\n flushAt: 1,\n flushInterval: 0,\n disableGeoip: false,\n });\n this.client.register({ mastraSource: MASTRA_SOURCE });\n debugAnalytics('enabled', { host, distinctId: this.distinctId, version });\n }\n\n capture(event: MastraCodeAnalyticsEvent, properties?: Record<string, unknown>): void {\n try {\n const eventProperties = {\n ...this.getBaseProperties(),\n ...properties,\n };\n debugAnalytics('capture', { event, properties: eventProperties });\n this.client.capture({\n distinctId: this.distinctId,\n event,\n properties: eventProperties,\n });\n } catch (error) {\n debugAnalytics('capture failed', { event, error: error instanceof Error ? error.message : String(error) });\n // swallow analytics errors\n }\n }\n\n trackCommand(command: string, properties?: Record<string, unknown>): void {\n this.capture('mastracode_command_used', { command, ...properties });\n }\n\n trackInteractivePrompt(promptType: string, properties?: Record<string, unknown>): void {\n this.capture('mastracode_interactive_prompt_shown', { promptType, ...properties });\n }\n\n async shutdown(): Promise<void> {\n try {\n debugAnalytics('shutdown start');\n await this.client.shutdown();\n debugAnalytics('shutdown complete');\n } catch (error) {\n debugAnalytics('shutdown failed', { error: error instanceof Error ? error.message : String(error) });\n // swallow analytics errors\n }\n }\n\n isEnabled(): boolean {\n return true;\n }\n\n private getBaseProperties(): Record<string, unknown> {\n return {\n mastraSource: MASTRA_SOURCE,\n sessionId: this.sessionId,\n version: this.version,\n os: process.platform,\n osVersion: os.release(),\n nodeVersion: process.version,\n platform: process.arch,\n machineId: os.hostname(),\n };\n }\n}\n\nexport function isTelemetryDisabled(env: NodeJS.ProcessEnv = process.env): boolean {\n const value = env.MASTRA_TELEMETRY_DISABLED;\n if (!value) {\n return false;\n }\n\n return TRUTHY_DISABLED_VALUES.has(value.trim().toLowerCase());\n}\n\nexport function createMastraCodeAnalytics(options: MastraCodeAnalyticsOptions): MastraCodeAnalytics {\n if (isTelemetryDisabled()) {\n debugAnalytics('disabled by MASTRA_TELEMETRY_DISABLED', { value: process.env.MASTRA_TELEMETRY_DISABLED });\n return new NoopMastraCodeAnalytics();\n }\n\n return new PostHogMastraCodeAnalytics(options);\n}\n"],"mappings":"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"}
@@ -1,28 +1,42 @@
1
+ //#region src/auth/authorization-input.ts
2
+ /**
3
+ * Forgiving parser for user-pasted OAuth authorization input.
4
+ *
5
+ * Accepts, in order of preference:
6
+ * - a full redirect URL (`https://.../callback?code=...&state=...`)
7
+ * - the `code#state` form shown on Anthropic's hosted callback page
8
+ * - a raw query string (`code=...&state=...`)
9
+ * - a bare authorization code
10
+ *
11
+ * Ported from pi-mono's `parseAuthorizationInput`.
12
+ */
1
13
  function parseAuthorizationInput(input) {
2
- const value = input.trim();
3
- if (!value) return {};
4
- try {
5
- const url = new URL(value);
6
- return {
7
- code: url.searchParams.get("code") ?? void 0,
8
- state: url.searchParams.get("state") ?? void 0
9
- };
10
- } catch {
11
- }
12
- if (value.includes("#")) {
13
- const [code, state] = value.split("#", 2);
14
- return { code, state };
15
- }
16
- if (value.includes("code=")) {
17
- const params = new URLSearchParams(value);
18
- return {
19
- code: params.get("code") ?? void 0,
20
- state: params.get("state") ?? void 0
21
- };
22
- }
23
- return { code: value };
14
+ const value = input.trim();
15
+ if (!value) return {};
16
+ try {
17
+ const url = new URL(value);
18
+ return {
19
+ code: url.searchParams.get("code") ?? void 0,
20
+ state: url.searchParams.get("state") ?? void 0
21
+ };
22
+ } catch {}
23
+ if (value.includes("#")) {
24
+ const [code, state] = value.split("#", 2);
25
+ return {
26
+ code,
27
+ state
28
+ };
29
+ }
30
+ if (value.includes("code=")) {
31
+ const params = new URLSearchParams(value);
32
+ return {
33
+ code: params.get("code") ?? void 0,
34
+ state: params.get("state") ?? void 0
35
+ };
36
+ }
37
+ return { code: value };
24
38
  }
25
- export {
26
- parseAuthorizationInput
27
- };
39
+ //#endregion
40
+ export { parseAuthorizationInput };
41
+
28
42
  //# sourceMappingURL=authorization-input.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/auth/authorization-input.ts"],"sourcesContent":["/**\n * Forgiving parser for user-pasted OAuth authorization input.\n *\n * Accepts, in order of preference:\n * - a full redirect URL (`https://.../callback?code=...&state=...`)\n * - the `code#state` form shown on Anthropic's hosted callback page\n * - a raw query string (`code=...&state=...`)\n * - a bare authorization code\n *\n * Ported from pi-mono's `parseAuthorizationInput`.\n */\nexport function parseAuthorizationInput(input: string): {\n code?: string;\n state?: string;\n} {\n const value = input.trim();\n if (!value) return {};\n\n try {\n const url = new URL(value);\n return {\n code: url.searchParams.get('code') ?? undefined,\n state: url.searchParams.get('state') ?? undefined,\n };\n } catch {\n // not a URL\n }\n\n if (value.includes('#')) {\n const [code, state] = value.split('#', 2);\n return { code, state };\n }\n\n if (value.includes('code=')) {\n const params = new URLSearchParams(value);\n return {\n code: params.get('code') ?? undefined,\n state: params.get('state') ?? undefined,\n };\n }\n\n return { code: value };\n}\n"],"mappings":"AAWO,SAAS,wBAAwB,OAGtC;AACA,QAAM,QAAQ,MAAM,KAAK;AACzB,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,KAAK;AACzB,WAAO;AAAA,MACL,MAAM,IAAI,aAAa,IAAI,MAAM,KAAK;AAAA,MACtC,OAAO,IAAI,aAAa,IAAI,OAAO,KAAK;AAAA,IAC1C;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,MAAI,MAAM,SAAS,GAAG,GAAG;AACvB,UAAM,CAAC,MAAM,KAAK,IAAI,MAAM,MAAM,KAAK,CAAC;AACxC,WAAO,EAAE,MAAM,MAAM;AAAA,EACvB;AAEA,MAAI,MAAM,SAAS,OAAO,GAAG;AAC3B,UAAM,SAAS,IAAI,gBAAgB,KAAK;AACxC,WAAO;AAAA,MACL,MAAM,OAAO,IAAI,MAAM,KAAK;AAAA,MAC5B,OAAO,OAAO,IAAI,OAAO,KAAK;AAAA,IAChC;AAAA,EACF;AAEA,SAAO,EAAE,MAAM,MAAM;AACvB;","names":[]}
1
+ {"version":3,"file":"authorization-input.js","names":[],"sources":["../../src/auth/authorization-input.ts"],"sourcesContent":["/**\n * Forgiving parser for user-pasted OAuth authorization input.\n *\n * Accepts, in order of preference:\n * - a full redirect URL (`https://.../callback?code=...&state=...`)\n * - the `code#state` form shown on Anthropic's hosted callback page\n * - a raw query string (`code=...&state=...`)\n * - a bare authorization code\n *\n * Ported from pi-mono's `parseAuthorizationInput`.\n */\nexport function parseAuthorizationInput(input: string): {\n code?: string;\n state?: string;\n} {\n const value = input.trim();\n if (!value) return {};\n\n try {\n const url = new URL(value);\n return {\n code: url.searchParams.get('code') ?? undefined,\n state: url.searchParams.get('state') ?? undefined,\n };\n } catch {\n // not a URL\n }\n\n if (value.includes('#')) {\n const [code, state] = value.split('#', 2);\n return { code, state };\n }\n\n if (value.includes('code=')) {\n const params = new URLSearchParams(value);\n return {\n code: params.get('code') ?? undefined,\n state: params.get('state') ?? undefined,\n };\n }\n\n return { code: value };\n}\n"],"mappings":";;;;;;;;;;;;AAWA,SAAgB,wBAAwB,OAGtC;CACA,MAAM,QAAQ,MAAM,KAAK;CACzB,IAAI,CAAC,OAAO,OAAO,CAAC;CAEpB,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,KAAK;EACzB,OAAO;GACL,MAAM,IAAI,aAAa,IAAI,MAAM,KAAK,KAAA;GACtC,OAAO,IAAI,aAAa,IAAI,OAAO,KAAK,KAAA;EAC1C;CACF,QAAQ,CAER;CAEA,IAAI,MAAM,SAAS,GAAG,GAAG;EACvB,MAAM,CAAC,MAAM,SAAS,MAAM,MAAM,KAAK,CAAC;EACxC,OAAO;GAAE;GAAM;EAAM;CACvB;CAEA,IAAI,MAAM,SAAS,OAAO,GAAG;EAC3B,MAAM,SAAS,IAAI,gBAAgB,KAAK;EACxC,OAAO;GACL,MAAM,OAAO,IAAI,MAAM,KAAK,KAAA;GAC5B,OAAO,OAAO,IAAI,OAAO,KAAK,KAAA;EAChC;CACF;CAEA,OAAO,EAAE,MAAM,MAAM;AACvB"}
@@ -1,97 +1,129 @@
1
+ //#region src/auth/device-code.ts
2
+ /**
3
+ * Generic RFC 8628 (OAuth 2.0 Device Authorization Grant) polling helpers.
4
+ *
5
+ * Ported from pi-mono's device-code utility, restructured as a single-step
6
+ * API so the same poll semantics can be driven two ways:
7
+ * - `pollDeviceCodeUntilComplete()` — blocking loop for TUI flows.
8
+ * - `stepDeviceCodePoll()` — exactly one upstream poll per call, with a
9
+ * JSON-serializable `DeviceCodePollState` so web routes can persist the
10
+ * state between HTTP requests (any replica can continue the poll).
11
+ *
12
+ * Inspired by pi-mono:
13
+ * https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/device-code.ts
14
+ */
1
15
  const DEFAULT_INTERVAL_SECONDS = 5;
2
16
  const INITIAL_POLL_INTERVAL_MULTIPLIER = 1.2;
3
17
  const SLOW_DOWN_POLL_INTERVAL_MULTIPLIER = 1.4;
4
18
  const SLOW_DOWN_INTERVAL_INCREMENT_MS = 5e3;
5
19
  function createDeviceCodePollState(options) {
6
- const now = options.now ?? Date.now();
7
- const intervalSeconds = typeof options.intervalSeconds === "number" && options.intervalSeconds > 0 ? options.intervalSeconds : DEFAULT_INTERVAL_SECONDS;
8
- return {
9
- deadlineAt: now + options.expiresInSeconds * 1e3,
10
- intervalMs: Math.max(1e3, Math.floor(intervalSeconds * 1e3)),
11
- slowDownResponses: 0
12
- };
20
+ const now = options.now ?? Date.now();
21
+ const intervalSeconds = typeof options.intervalSeconds === "number" && options.intervalSeconds > 0 ? options.intervalSeconds : DEFAULT_INTERVAL_SECONDS;
22
+ return {
23
+ deadlineAt: now + options.expiresInSeconds * 1e3,
24
+ intervalMs: Math.max(1e3, Math.floor(intervalSeconds * 1e3)),
25
+ slowDownResponses: 0
26
+ };
13
27
  }
14
28
  function timeoutMessage(state) {
15
- if (state.slowDownResponses > 0) {
16
- return "Device flow timed out after one or more slow_down responses. This is often caused by clock drift in WSL or VM environments. Please sync or restart the VM clock and try again.";
17
- }
18
- return "Device flow timed out";
29
+ if (state.slowDownResponses > 0) return "Device flow timed out after one or more slow_down responses. This is often caused by clock drift in WSL or VM environments. Please sync or restart the VM clock and try again.";
30
+ return "Device flow timed out";
19
31
  }
32
+ /**
33
+ * Delay to wait before the next poll, honoring slow_down growth and clamped
34
+ * to the remaining lifetime of the device code.
35
+ */
20
36
  function nextPollDelayMs(state, now = Date.now()) {
21
- const multiplier = state.slowDownResponses > 0 ? SLOW_DOWN_POLL_INTERVAL_MULTIPLIER : INITIAL_POLL_INTERVAL_MULTIPLIER;
22
- const remainingMs = Math.max(0, state.deadlineAt - now);
23
- return Math.min(Math.ceil(state.intervalMs * multiplier), remainingMs);
37
+ const multiplier = state.slowDownResponses > 0 ? SLOW_DOWN_POLL_INTERVAL_MULTIPLIER : INITIAL_POLL_INTERVAL_MULTIPLIER;
38
+ const remainingMs = Math.max(0, state.deadlineAt - now);
39
+ return Math.min(Math.ceil(state.intervalMs * multiplier), remainingMs);
24
40
  }
41
+ /**
42
+ * Perform exactly one upstream poll and fold the outcome into the poll state.
43
+ * Never throws for flow-level conditions — timeouts and provider errors are
44
+ * reported as `{ status: 'failed' }` so callers can persist/report them.
45
+ */
25
46
  async function stepDeviceCodePoll(state, pollOnce, now = Date.now()) {
26
- if (now >= state.deadlineAt) {
27
- return { status: "failed", error: timeoutMessage(state), state };
28
- }
29
- const outcome = await pollOnce();
30
- switch (outcome.status) {
31
- case "complete":
32
- return { status: "complete", result: outcome.result, state };
33
- case "failed":
34
- return { status: "failed", error: outcome.error, state };
35
- case "slow_down": {
36
- const next = {
37
- ...state,
38
- slowDownResponses: state.slowDownResponses + 1,
39
- // RFC 8628 section 3.5: grow the interval by 5 seconds, unless the
40
- // server told us the interval to use.
41
- intervalMs: typeof outcome.intervalSeconds === "number" && outcome.intervalSeconds > 0 ? outcome.intervalSeconds * 1e3 : Math.max(1e3, state.intervalMs + SLOW_DOWN_INTERVAL_INCREMENT_MS)
42
- };
43
- return { status: "slow_down", nextPollMs: nextPollDelayMs(next, now), state: next };
44
- }
45
- case "pending": {
46
- const next = typeof outcome.intervalSeconds === "number" && outcome.intervalSeconds > 0 ? { ...state, intervalMs: Math.max(1e3, outcome.intervalSeconds * 1e3) } : state;
47
- return { status: "pending", nextPollMs: nextPollDelayMs(next, now), state: next };
48
- }
49
- }
47
+ if (now >= state.deadlineAt) return {
48
+ status: "failed",
49
+ error: timeoutMessage(state),
50
+ state
51
+ };
52
+ const outcome = await pollOnce();
53
+ switch (outcome.status) {
54
+ case "complete": return {
55
+ status: "complete",
56
+ result: outcome.result,
57
+ state
58
+ };
59
+ case "failed": return {
60
+ status: "failed",
61
+ error: outcome.error,
62
+ state
63
+ };
64
+ case "slow_down": {
65
+ const next = {
66
+ ...state,
67
+ slowDownResponses: state.slowDownResponses + 1,
68
+ intervalMs: typeof outcome.intervalSeconds === "number" && outcome.intervalSeconds > 0 ? outcome.intervalSeconds * 1e3 : Math.max(1e3, state.intervalMs + SLOW_DOWN_INTERVAL_INCREMENT_MS)
69
+ };
70
+ return {
71
+ status: "slow_down",
72
+ nextPollMs: nextPollDelayMs(next, now),
73
+ state: next
74
+ };
75
+ }
76
+ case "pending": {
77
+ const next = typeof outcome.intervalSeconds === "number" && outcome.intervalSeconds > 0 ? {
78
+ ...state,
79
+ intervalMs: Math.max(1e3, outcome.intervalSeconds * 1e3)
80
+ } : state;
81
+ return {
82
+ status: "pending",
83
+ nextPollMs: nextPollDelayMs(next, now),
84
+ state: next
85
+ };
86
+ }
87
+ }
50
88
  }
89
+ /** Sleep that can be interrupted by an AbortSignal. */
51
90
  function abortableSleep(ms, signal) {
52
- return new Promise((resolve, reject) => {
53
- if (signal?.aborted) {
54
- reject(new Error("Login cancelled"));
55
- return;
56
- }
57
- let timeout;
58
- const onAbort = () => {
59
- clearTimeout(timeout);
60
- reject(new Error("Login cancelled"));
61
- };
62
- timeout = setTimeout(() => {
63
- signal?.removeEventListener("abort", onAbort);
64
- resolve();
65
- }, ms);
66
- signal?.addEventListener("abort", onAbort, { once: true });
67
- });
91
+ return new Promise((resolve, reject) => {
92
+ if (signal?.aborted) {
93
+ reject(/* @__PURE__ */ new Error("Login cancelled"));
94
+ return;
95
+ }
96
+ let timeout;
97
+ const onAbort = () => {
98
+ clearTimeout(timeout);
99
+ reject(/* @__PURE__ */ new Error("Login cancelled"));
100
+ };
101
+ timeout = setTimeout(() => {
102
+ signal?.removeEventListener("abort", onAbort);
103
+ resolve();
104
+ }, ms);
105
+ signal?.addEventListener("abort", onAbort, { once: true });
106
+ });
68
107
  }
108
+ /**
109
+ * Blocking poll loop for TUI flows: waits the appropriate interval between
110
+ * polls, honors slow_down growth, aborts on the signal, and throws on
111
+ * failure/timeout (with a clock-drift hint after slow_down responses).
112
+ */
69
113
  async function pollDeviceCodeUntilComplete(options) {
70
- let state = options.state;
71
- const sleep = options.sleep ?? abortableSleep;
72
- while (true) {
73
- if (options.signal?.aborted) {
74
- throw new Error("Login cancelled");
75
- }
76
- if (Date.now() >= state.deadlineAt) {
77
- throw new Error(timeoutMessage(state));
78
- }
79
- await sleep(nextPollDelayMs(state), options.signal);
80
- const step = await stepDeviceCodePoll(state, options.pollOnce);
81
- state = step.state;
82
- if (step.status === "complete") {
83
- return step.result;
84
- }
85
- if (step.status === "failed") {
86
- throw new Error(step.error);
87
- }
88
- }
114
+ let state = options.state;
115
+ const sleep = options.sleep ?? abortableSleep;
116
+ while (true) {
117
+ if (options.signal?.aborted) throw new Error("Login cancelled");
118
+ if (Date.now() >= state.deadlineAt) throw new Error(timeoutMessage(state));
119
+ await sleep(nextPollDelayMs(state), options.signal);
120
+ const step = await stepDeviceCodePoll(state, options.pollOnce);
121
+ state = step.state;
122
+ if (step.status === "complete") return step.result;
123
+ if (step.status === "failed") throw new Error(step.error);
124
+ }
89
125
  }
90
- export {
91
- abortableSleep,
92
- createDeviceCodePollState,
93
- nextPollDelayMs,
94
- pollDeviceCodeUntilComplete,
95
- stepDeviceCodePoll
96
- };
126
+ //#endregion
127
+ export { abortableSleep, createDeviceCodePollState, nextPollDelayMs, pollDeviceCodeUntilComplete, stepDeviceCodePoll };
128
+
97
129
  //# sourceMappingURL=device-code.js.map