@getpaseo/server 0.1.100 → 0.1.102-beta.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 (172) hide show
  1. package/dist/scripts/supervisor.js +26 -8
  2. package/dist/server/executable-resolution/windows.js +3 -0
  3. package/dist/server/server/agent/activity-curator.d.ts +17 -0
  4. package/dist/server/server/agent/activity-curator.js +101 -24
  5. package/dist/server/server/agent/agent-manager.d.ts +10 -0
  6. package/dist/server/server/agent/agent-manager.js +69 -27
  7. package/dist/server/server/agent/agent-sdk-types.d.ts +15 -2
  8. package/dist/server/server/agent/mcp-server.d.ts +2 -45
  9. package/dist/server/server/agent/mcp-server.js +45 -1985
  10. package/dist/server/server/agent/prompt-attachments.js +6 -2
  11. package/dist/server/server/agent/provider-snapshot-manager.d.ts +12 -1
  12. package/dist/server/server/agent/provider-snapshot-manager.js +132 -42
  13. package/dist/server/server/agent/providers/acp-agent.d.ts +27 -1
  14. package/dist/server/server/agent/providers/acp-agent.js +178 -27
  15. package/dist/server/server/agent/providers/claude/agent.js +111 -24
  16. package/dist/server/server/agent/providers/claude/query.d.ts +3 -0
  17. package/dist/server/server/agent/providers/claude/query.js +4 -2
  18. package/dist/server/server/agent/providers/codex-app-server-agent.js +6 -57
  19. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +1 -0
  20. package/dist/server/server/agent/providers/diagnostic-utils.js +1 -1
  21. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +3 -0
  22. package/dist/server/server/agent/providers/generic-acp-agent.js +41 -23
  23. package/dist/server/server/agent/providers/mock-load-test-agent.js +12 -2
  24. package/dist/server/server/agent/providers/opencode/paths.d.ts +2 -0
  25. package/dist/server/server/agent/providers/opencode/paths.js +7 -0
  26. package/dist/server/server/agent/providers/opencode/server-manager.d.ts +2 -0
  27. package/dist/server/server/agent/providers/opencode/server-manager.js +34 -5
  28. package/dist/server/server/agent/providers/opencode-agent.d.ts +4 -0
  29. package/dist/server/server/agent/providers/opencode-agent.js +14 -2
  30. package/dist/server/server/agent/providers/pi/agent.d.ts +5 -1
  31. package/dist/server/server/agent/providers/pi/agent.js +12 -3
  32. package/dist/server/server/agent/providers/provider-image-output.d.ts +5 -0
  33. package/dist/server/server/agent/providers/provider-image-output.js +61 -1
  34. package/dist/server/server/agent/tools/paseo-tools.d.ts +48 -0
  35. package/dist/server/server/agent/tools/paseo-tools.js +2119 -0
  36. package/dist/server/server/agent/tools/types.d.ts +36 -0
  37. package/dist/server/server/agent/tools/types.js +2 -0
  38. package/dist/server/server/bootstrap.d.ts +7 -1
  39. package/dist/server/server/bootstrap.js +89 -62
  40. package/dist/server/server/config.d.ts +2 -0
  41. package/dist/server/server/config.js +57 -1
  42. package/dist/server/server/daemon-worker.js +19 -7
  43. package/dist/server/server/lifecycle-reasons.d.ts +4 -0
  44. package/dist/server/server/lifecycle-reasons.js +6 -0
  45. package/dist/server/server/persisted-config.d.ts +12 -0
  46. package/dist/server/server/persisted-config.js +18 -2
  47. package/dist/server/server/process-diagnostics.d.ts +17 -0
  48. package/dist/server/server/process-diagnostics.js +22 -0
  49. package/dist/server/server/relay-transport.js +1 -0
  50. package/dist/server/server/resolve-worktree-creation-intent.js +3 -1
  51. package/dist/server/server/session/agent-updates/agent-updates-service.d.ts +59 -0
  52. package/dist/server/server/session/agent-updates/agent-updates-service.js +220 -0
  53. package/dist/server/server/session/checkout/checkout-session.d.ts +13 -15
  54. package/dist/server/server/session/checkout/checkout-session.js +18 -16
  55. package/dist/server/server/session/checkout/git-metadata-generator.d.ts +53 -0
  56. package/dist/server/server/session/checkout/git-metadata-generator.js +159 -0
  57. package/dist/server/server/session/daemon/daemon-self-update-session-controller.d.ts +32 -0
  58. package/dist/server/server/session/daemon/daemon-self-update-session-controller.js +88 -0
  59. package/dist/server/server/session/daemon/daemon-self-updater.d.ts +32 -0
  60. package/dist/server/server/session/daemon/daemon-self-updater.js +56 -0
  61. package/dist/server/server/session/daemon/daemon-session.d.ts +26 -0
  62. package/dist/server/server/session/daemon/daemon-session.js +50 -0
  63. package/dist/server/server/session/daemon/diagnostics.d.ts +41 -0
  64. package/dist/server/server/session/daemon/diagnostics.js +431 -0
  65. package/dist/server/server/session/daemon/install-origin.d.ts +7 -0
  66. package/dist/server/server/session/daemon/install-origin.js +64 -0
  67. package/dist/server/server/session/daemon/npm-global-cli.d.ts +29 -0
  68. package/dist/server/server/session/daemon/npm-global-cli.js +98 -0
  69. package/dist/server/server/session/git-mutation/git-mutation-service.d.ts +34 -0
  70. package/dist/server/server/session/git-mutation/git-mutation-service.js +71 -0
  71. package/dist/server/server/session/provider/provider-catalog-session.js +8 -4
  72. package/dist/server/server/session/workspace-git-observer/workspace-git-observer-service.d.ts +36 -0
  73. package/dist/server/server/session/workspace-git-observer/workspace-git-observer-service.js +134 -0
  74. package/dist/server/server/session/workspace-provisioning/workspace-provisioning-service.d.ts +34 -0
  75. package/dist/server/server/session/workspace-provisioning/workspace-provisioning-service.js +190 -0
  76. package/dist/server/server/session/workspace-scripts/workspace-scripts-service.d.ts +41 -0
  77. package/dist/server/server/session/workspace-scripts/workspace-scripts-service.js +100 -0
  78. package/dist/server/server/session.d.ts +12 -54
  79. package/dist/server/server/session.js +187 -970
  80. package/dist/server/server/speech/providers/openai/config.d.ts +1 -2
  81. package/dist/server/server/speech/providers/openai/config.js +13 -9
  82. package/dist/server/server/speech/providers/openai/runtime.js +2 -16
  83. package/dist/server/server/speech/providers/openai/stt.d.ts +1 -0
  84. package/dist/server/server/speech/providers/openai/stt.js +4 -2
  85. package/dist/server/server/speech/providers/openai/tts.d.ts +1 -0
  86. package/dist/server/server/speech/providers/openai/tts.js +1 -0
  87. package/dist/server/server/web-ui.d.ts +10 -0
  88. package/dist/server/server/web-ui.js +205 -0
  89. package/dist/server/server/websocket/runtime-metrics.d.ts +23 -0
  90. package/dist/server/server/websocket-server.d.ts +4 -2
  91. package/dist/server/server/websocket-server.js +215 -52
  92. package/dist/server/server/worktree-bootstrap.d.ts +1 -1
  93. package/dist/server/server/worktree-branch-name-generator.js +3 -1
  94. package/dist/server/services/quota-fetcher/manifest.js +5 -0
  95. package/dist/server/services/quota-fetcher/providers/minimax.d.ts +29 -0
  96. package/dist/server/services/quota-fetcher/providers/minimax.js +227 -0
  97. package/dist/server/terminal/agent-hooks/agent-hook-installer.js +2 -2
  98. package/dist/server/utils/checkout-git.js +203 -25
  99. package/dist/server/utils/directory-suggestions.js +1 -4
  100. package/dist/server/utils/path.d.ts +2 -0
  101. package/dist/server/utils/path.js +13 -0
  102. package/dist/server/utils/worktree.d.ts +1 -0
  103. package/dist/server/utils/worktree.js +92 -11
  104. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css +1 -0
  105. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css.br +0 -0
  106. package/dist/server/web-ui/_expo/static/css/xterm-3bb1704bf6cb0876640973dc0244b4cb.css.gz +0 -0
  107. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js +1 -0
  108. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js.br +0 -0
  109. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-b01555c9b42665a03988c0a0032ef528.js.gz +0 -0
  110. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js +1 -0
  111. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js.br +0 -0
  112. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-648388eca5c510b496e1eddf523f70ff.js.gz +0 -0
  113. package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js +16157 -0
  114. package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js.br +0 -0
  115. package/dist/server/web-ui/_expo/static/js/web/index-0ebbea2cd337f0c0680fdb3f8d4d5af3.js.gz +0 -0
  116. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js +1 -0
  117. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js.br +0 -0
  118. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-c64fa2416284927857a39087fd8d1332.js.gz +0 -0
  119. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js +3 -0
  120. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js.br +0 -0
  121. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-a9784226715772edf87ef36c596599c2.js.gz +0 -0
  122. package/dist/server/web-ui/apple-touch-icon.png +0 -0
  123. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon-mask.0a328cd9c1afd0afe8e3b1ec5165b1b4.png +0 -0
  124. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/back-icon.35ba0eaec5a4f5ed12ca16fabeae451d.png +0 -0
  125. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55.png +0 -0
  126. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@2x.png +0 -0
  127. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@3x.png +0 -0
  128. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/clear-icon.c94f6478e7ae0cdd9f15de1fcb9e5e55@4x.png +0 -0
  129. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7.png +0 -0
  130. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@2x.png +0 -0
  131. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@3x.png +0 -0
  132. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/close-icon.808e1b1b9b53114ec2838071a7e6daa7@4x.png +0 -0
  133. package/dist/server/web-ui/assets/__node_modules/@react-navigation/elements/lib/module/assets/search-icon.286d67d3f74808a60a78d3ebf1a5fb57.png +0 -0
  134. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png +0 -0
  135. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/error.d1ea1496f9057eb392d5bbf3732a61b7.png +0 -0
  136. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/file.19eeb73b9593a38f8e9f418337fc7d10.png +0 -0
  137. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/forward.d8b800c443b8972542883e0b9de2bdc6.png +0 -0
  138. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/pkg.ab19f4cbc543357183a20571f68380a3.png +0 -0
  139. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/sitemap.412dd9275b6b48ad28f5e3d81bb1f626.png +0 -0
  140. package/dist/server/web-ui/assets/__node_modules/expo-router/assets/unmatched.20e71bdf79e3a97bf55fd9e164041578.png +0 -0
  141. package/dist/server/web-ui/assets/assets/images/editor-apps/antigravity.6e91a685c33435e0b466a56db86cf141.png +0 -0
  142. package/dist/server/web-ui/assets/assets/images/editor-apps/cursor.c31d6bce4fe9aadc3fe59962f4c4fcf3.png +0 -0
  143. package/dist/server/web-ui/assets/assets/images/editor-apps/file-explorer.3e15e8f72c825c85ce336bcb0cdef776.png +0 -0
  144. package/dist/server/web-ui/assets/assets/images/editor-apps/finder.7f68fc2c475621a672e1be09309d5567.png +0 -0
  145. package/dist/server/web-ui/assets/assets/images/editor-apps/vscode.832bdb4c685d930f1c864c793703600b.png +0 -0
  146. package/dist/server/web-ui/assets/assets/images/editor-apps/webstorm.aa5dc2cd8c20cc0a155c4c5c5ab3c5f5.png +0 -0
  147. package/dist/server/web-ui/assets/assets/images/editor-apps/zed.f3a670b7f9aa226da4fe53fb86f1abbd.png +0 -0
  148. package/dist/server/web-ui/assets/assets/images/favicon-dark-attention.882b3a27dcb2073e9e31b334f9ed9728.png +0 -0
  149. package/dist/server/web-ui/assets/assets/images/favicon-dark-running.8112342ff0d39e047a7f8d4fad9402f3.png +0 -0
  150. package/dist/server/web-ui/assets/assets/images/favicon-dark.8005ed36ac07a5a7c60de25780897bd4.png +0 -0
  151. package/dist/server/web-ui/assets/assets/images/favicon-light-attention.882b3a27dcb2073e9e31b334f9ed9728.png +0 -0
  152. package/dist/server/web-ui/assets/assets/images/favicon-light-running.8112342ff0d39e047a7f8d4fad9402f3.png +0 -0
  153. package/dist/server/web-ui/assets/assets/images/favicon-light.8005ed36ac07a5a7c60de25780897bd4.png +0 -0
  154. package/dist/server/web-ui/assets/assets/images/notification-icon.3bf81d33ddbf380606bdd248ba83e158.png +0 -0
  155. package/dist/server/web-ui/favicon.ico +0 -0
  156. package/dist/server/web-ui/index.html +90 -0
  157. package/dist/server/web-ui/index.html.br +0 -0
  158. package/dist/server/web-ui/index.html.gz +0 -0
  159. package/dist/server/web-ui/manifest.json +27 -0
  160. package/dist/server/web-ui/manifest.json.br +0 -0
  161. package/dist/server/web-ui/manifest.json.gz +0 -0
  162. package/dist/server/web-ui/metadata.json +1 -0
  163. package/dist/server/web-ui/metadata.json.br +1 -0
  164. package/dist/server/web-ui/metadata.json.gz +0 -0
  165. package/dist/server/web-ui/pwa-icon-192.png +0 -0
  166. package/dist/server/web-ui/pwa-icon-512.png +0 -0
  167. package/dist/server/web-ui/robots.txt +2 -0
  168. package/dist/src/executable-resolution/windows.js +3 -0
  169. package/dist/src/server/persisted-config.js +18 -2
  170. package/package.json +7 -7
  171. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts +0 -42
  172. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +0 -168
@@ -0,0 +1,227 @@
1
+ import { existsSync, promises as fs } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { z } from "zod";
5
+ import { ApiNumberSchema, ApiOptionalStringSchema, fetchProviderApi, unavailableUsage, windowFromUsedPct, } from "../usage.js";
6
+ const MINIMAX_GLOBAL_BASE_URL = "https://api.minimax.io";
7
+ const MINIMAX_CN_BASE_URL = "https://api.minimaxi.com";
8
+ const MINIMAX_CREDENTIALS_PATH = join(homedir(), ".mmx", "credentials.json");
9
+ const MINIMAX_CONFIG_PATH = join(homedir(), ".mmx", "config.json");
10
+ const MiniMaxModelRemainSchema = z.object({
11
+ model_name: ApiOptionalStringSchema,
12
+ start_time: ApiNumberSchema.optional(),
13
+ end_time: ApiNumberSchema.optional(),
14
+ remains_time: ApiNumberSchema.optional(),
15
+ current_interval_total_count: ApiNumberSchema.optional(),
16
+ current_interval_usage_count: ApiNumberSchema.optional(),
17
+ current_interval_remaining_percent: ApiNumberSchema.optional(),
18
+ current_weekly_total_count: ApiNumberSchema.optional(),
19
+ current_weekly_usage_count: ApiNumberSchema.optional(),
20
+ current_weekly_remaining_percent: ApiNumberSchema.optional(),
21
+ current_interval_status: ApiNumberSchema.optional(),
22
+ current_weekly_status: ApiNumberSchema.optional(),
23
+ weekly_start_time: ApiNumberSchema.optional(),
24
+ weekly_end_time: ApiNumberSchema.optional(),
25
+ weekly_remains_time: ApiNumberSchema.optional(),
26
+ weekly_boost_permille: ApiNumberSchema.optional(),
27
+ });
28
+ const MiniMaxQuotaResponseSchema = z.object({
29
+ model_remains: z.array(MiniMaxModelRemainSchema).optional(),
30
+ });
31
+ const MiniMaxCredentialsSchema = z.object({
32
+ access_token: z.string().optional(),
33
+ refresh_token: z.string().optional(),
34
+ expires_at: ApiOptionalStringSchema,
35
+ resource_url: ApiOptionalStringSchema,
36
+ });
37
+ const MiniMaxConfigSchema = z.object({
38
+ api_key: z.string().optional(),
39
+ region: z.string().optional(),
40
+ base_url: ApiOptionalStringSchema,
41
+ oauth: MiniMaxCredentialsSchema.optional(),
42
+ });
43
+ function resolveBaseUrl(input) {
44
+ const explicit = input.baseUrl;
45
+ if (explicit && explicit.startsWith("http"))
46
+ return explicit;
47
+ if (input.region === "cn")
48
+ return MINIMAX_CN_BASE_URL;
49
+ return MINIMAX_GLOBAL_BASE_URL;
50
+ }
51
+ function computeUsedPct(remaining, total) {
52
+ if (typeof remaining !== "number" || typeof total !== "number")
53
+ return null;
54
+ if (!Number.isFinite(total) || total <= 0)
55
+ return null;
56
+ if (!Number.isFinite(remaining))
57
+ return null;
58
+ const used = total - remaining;
59
+ return Math.max(0, Math.min(100, (used / total) * 100));
60
+ }
61
+ function epochMsToIso(value) {
62
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0)
63
+ return null;
64
+ return new Date(value).toISOString();
65
+ }
66
+ function toneForStatus(status) {
67
+ if (status === 2)
68
+ return "danger";
69
+ if (status === 3)
70
+ return "default";
71
+ return "ok";
72
+ }
73
+ function toIntervalWindow(modelName, model) {
74
+ const total = model.current_interval_total_count ?? null;
75
+ const used = model.current_interval_usage_count ?? null;
76
+ const remainingPercent = model.current_interval_remaining_percent ?? null;
77
+ const usedPct = typeof remainingPercent === "number" && Number.isFinite(remainingPercent)
78
+ ? Math.max(0, Math.min(100, 100 - remainingPercent))
79
+ : computeUsedPct(typeof total === "number" && typeof used === "number" ? total - used : null, total);
80
+ if (usedPct === null)
81
+ return null;
82
+ return windowFromUsedPct({
83
+ id: `interval_${modelName}`,
84
+ label: `${modelName} · Interval`,
85
+ utilizationPct: usedPct,
86
+ resetsAt: epochMsToIso(model.end_time),
87
+ tone: toneForStatus(model.current_interval_status),
88
+ });
89
+ }
90
+ function toWeeklyWindow(modelName, model) {
91
+ const total = model.current_weekly_total_count ?? null;
92
+ const used = model.current_weekly_usage_count ?? null;
93
+ const remainingPercent = model.current_weekly_remaining_percent ?? null;
94
+ let usedPct = null;
95
+ if (typeof remainingPercent === "number" && Number.isFinite(remainingPercent)) {
96
+ usedPct = Math.max(0, Math.min(100, 100 - remainingPercent));
97
+ }
98
+ else if (typeof total === "number" && typeof used === "number") {
99
+ usedPct = computeUsedPct(total - used, total);
100
+ }
101
+ if (usedPct === null)
102
+ return null;
103
+ return windowFromUsedPct({
104
+ id: `weekly_${modelName}`,
105
+ label: `${modelName} · Weekly`,
106
+ utilizationPct: usedPct,
107
+ resetsAt: epochMsToIso(model.weekly_end_time),
108
+ tone: toneForStatus(model.current_weekly_status),
109
+ });
110
+ }
111
+ export class MiniMaxQuotaProvider {
112
+ constructor(options) {
113
+ this.providerId = "minimax";
114
+ this.displayName = "MiniMax";
115
+ this.logger = options.logger;
116
+ this.fetchApi = options.fetch ?? fetch;
117
+ this.configPath = options.configPath ?? MINIMAX_CONFIG_PATH;
118
+ this.credentialsPath = options.credentialsPath ?? MINIMAX_CREDENTIALS_PATH;
119
+ this.env = options.env ?? process.env;
120
+ this.now = options.now ?? Date.now;
121
+ }
122
+ async fetchUsage() {
123
+ const auth = await this.resolveAuth();
124
+ if (!auth)
125
+ return unavailableUsage(this);
126
+ const res = await fetchProviderApi(this.fetchApi, `${auth.baseUrl}/v1/token_plan/remains`, {
127
+ headers: {
128
+ Authorization: `Bearer ${auth.token}`,
129
+ Accept: "application/json",
130
+ },
131
+ });
132
+ if (!res.ok) {
133
+ this.logger.debug({ status: res.status }, "MiniMax usage fetch failed");
134
+ return unavailableUsage(this);
135
+ }
136
+ const resp = MiniMaxQuotaResponseSchema.parse(await res.json());
137
+ const models = resp.model_remains ?? [];
138
+ const windows = [];
139
+ for (const model of models) {
140
+ const name = model.model_name ?? "token-plan";
141
+ const intervalWindow = toIntervalWindow(name, model);
142
+ if (intervalWindow)
143
+ windows.push(intervalWindow);
144
+ const weeklyWindow = toWeeklyWindow(name, model);
145
+ if (weeklyWindow)
146
+ windows.push(weeklyWindow);
147
+ }
148
+ return {
149
+ providerId: this.providerId,
150
+ displayName: this.displayName,
151
+ status: windows.length > 0 ? "available" : "unavailable",
152
+ planLabel: null,
153
+ windows,
154
+ balances: [],
155
+ details: [],
156
+ error: null,
157
+ };
158
+ }
159
+ async resolveAuth() {
160
+ const envToken = this.env["MINIMAX_API_KEY"];
161
+ if (envToken) {
162
+ const envBase = this.env["MINIMAX_BASE_URL"];
163
+ return {
164
+ token: envToken,
165
+ baseUrl: resolveBaseUrl({ baseUrl: envBase }),
166
+ };
167
+ }
168
+ const credentials = await this.readCredentials();
169
+ if (credentials?.access_token && !this.isExpired(credentials.expires_at)) {
170
+ return {
171
+ token: credentials.access_token,
172
+ baseUrl: resolveBaseUrl({ baseUrl: credentials.resource_url }),
173
+ };
174
+ }
175
+ const config = await this.readConfig();
176
+ if (config?.api_key) {
177
+ return {
178
+ token: config.api_key,
179
+ baseUrl: resolveBaseUrl({
180
+ baseUrl: config.base_url,
181
+ region: config.region,
182
+ }),
183
+ };
184
+ }
185
+ if (config?.oauth?.access_token && !this.isExpired(config.oauth.expires_at)) {
186
+ return {
187
+ token: config.oauth.access_token,
188
+ baseUrl: resolveBaseUrl({
189
+ baseUrl: config.oauth.resource_url ?? config.base_url,
190
+ region: config.region,
191
+ }),
192
+ };
193
+ }
194
+ return null;
195
+ }
196
+ isExpired(expiresAt) {
197
+ if (!expiresAt)
198
+ return false;
199
+ const parsed = Date.parse(expiresAt);
200
+ if (!Number.isFinite(parsed))
201
+ return false;
202
+ return parsed <= this.now();
203
+ }
204
+ async readCredentials() {
205
+ if (!existsSync(this.credentialsPath))
206
+ return null;
207
+ try {
208
+ const raw = JSON.parse(await fs.readFile(this.credentialsPath, "utf8"));
209
+ return MiniMaxCredentialsSchema.parse(raw);
210
+ }
211
+ catch {
212
+ return null;
213
+ }
214
+ }
215
+ async readConfig() {
216
+ if (!existsSync(this.configPath))
217
+ return null;
218
+ try {
219
+ const raw = JSON.parse(await fs.readFile(this.configPath, "utf8"));
220
+ return MiniMaxConfigSchema.parse(raw);
221
+ }
222
+ catch {
223
+ return null;
224
+ }
225
+ }
226
+ }
227
+ //# sourceMappingURL=minimax.js.map
@@ -42,11 +42,11 @@ function resolveAgentHookInstallPath(install, options) {
42
42
  }
43
43
  export function buildAgentHookShellCommand(provider, event) {
44
44
  const hookCommand = `"\${PASEO_HOOK_CLI:-paseo}" hooks ${shellToken(provider.id)} ${shellToken(event.event)}`;
45
- return `[ -n "$PASEO_TERMINAL_ID" ] && ${hookCommand}`;
45
+ return `if [ -n "$PASEO_TERMINAL_ID" ]; then ${hookCommand}; fi`;
46
46
  }
47
47
  export function buildAgentHookWindowsCommand(provider, event) {
48
48
  const hookArgs = `hooks ${windowsToken(provider.id)} ${windowsToken(event.event)}`;
49
- return `if defined PASEO_TERMINAL_ID (if defined PASEO_HOOK_CLI ("%PASEO_HOOK_CLI%" ${hookArgs}) else (paseo ${hookArgs}))`;
49
+ return `if defined PASEO_TERMINAL_ID (if defined PASEO_HOOK_CLI ("%PASEO_HOOK_CLI%" ${hookArgs}) else (paseo ${hookArgs})) else (exit /b 0)`;
50
50
  }
51
51
  function installAgentHookPluginFile(install, options) {
52
52
  const configPath = resolveAgentHookInstallPath(install, options);
@@ -723,6 +723,20 @@ async function getGitConfigValue(cwd, key, context) {
723
723
  return null;
724
724
  }
725
725
  }
726
+ async function getGitRemotePushUrl(cwd, remoteName, context) {
727
+ try {
728
+ const { stdout } = await runGitCommand(["remote", "get-url", "--push", remoteName], {
729
+ cwd,
730
+ envOverlay: READ_ONLY_GIT_ENV,
731
+ logger: context?.logger,
732
+ });
733
+ const value = stdout.trim();
734
+ return value.length > 0 ? value : null;
735
+ }
736
+ catch {
737
+ return null;
738
+ }
739
+ }
726
740
  function parseBranchMergeHeadRef(mergeRef) {
727
741
  const prefix = "refs/heads/";
728
742
  if (!mergeRef?.startsWith(prefix)) {
@@ -735,22 +749,41 @@ async function resolvePullRequestStatusLookupTarget(cwd, currentBranch, context)
735
749
  if (context?.facts?.isGit && context.facts.pullRequestLookupTarget) {
736
750
  return context.facts.pullRequestLookupTarget;
737
751
  }
738
- const remoteName = await getGitConfigValue(cwd, `branch.${currentBranch}.remote`);
739
- if (!remoteName?.startsWith("paseo-pr-")) {
740
- return { headRef: currentBranch };
752
+ const branchRemoteName = await getGitConfigValue(cwd, `branch.${currentBranch}.remote`, context);
753
+ let branchMergeRef = null;
754
+ if (branchRemoteName) {
755
+ branchMergeRef = await getGitConfigValue(cwd, `branch.${currentBranch}.merge`, context);
741
756
  }
742
- const mergeRef = await getGitConfigValue(cwd, `branch.${currentBranch}.merge`);
743
- const trackedHeadRef = parseBranchMergeHeadRef(mergeRef);
744
- if (!trackedHeadRef) {
745
- return { headRef: currentBranch };
757
+ const localBranchTarget = buildPullRequestLookupTargetFromBranchConfig({
758
+ currentBranch,
759
+ branchRemoteName,
760
+ branchMergeRef,
761
+ branchRemoteUrl: null,
762
+ originRemoteUrl: null,
763
+ resolvedBaseRef: null,
764
+ });
765
+ if (localBranchTarget.headRef === currentBranch) {
766
+ const pushTarget = await resolvePullRequestLookupTargetFromPushConfig(cwd, currentBranch, null, null, context);
767
+ return pushTarget ?? localBranchTarget;
768
+ }
769
+ const [branchRemoteUrl, originRemoteUrl, resolvedBaseRef] = await Promise.all([
770
+ branchRemoteName ? getGitConfigValue(cwd, `remote.${branchRemoteName}.url`, context) : null,
771
+ getGitConfigValue(cwd, "remote.origin.url", context),
772
+ getResolvedBaseRefForCwd(cwd, context),
773
+ ]);
774
+ const branchTarget = buildPullRequestLookupTargetFromBranchConfig({
775
+ currentBranch,
776
+ branchRemoteName,
777
+ branchMergeRef,
778
+ branchRemoteUrl,
779
+ originRemoteUrl,
780
+ resolvedBaseRef,
781
+ });
782
+ if (branchTarget.headRef !== currentBranch || branchTarget.headRepositoryOwner) {
783
+ return branchTarget;
746
784
  }
747
- const remoteUrl = await getGitConfigValue(cwd, `remote.${remoteName}.url`);
748
- const remoteRepo = remoteUrl ? parseGitHubRepoFromRemote(remoteUrl) : null;
749
- const headRepositoryOwner = remoteRepo?.split("/")[0];
750
- return {
751
- headRef: trackedHeadRef,
752
- ...(headRepositoryOwner ? { headRepositoryOwner } : {}),
753
- };
785
+ const pushTarget = await resolvePullRequestLookupTargetFromPushConfig(cwd, currentBranch, originRemoteUrl, resolvedBaseRef, context);
786
+ return pushTarget ?? branchTarget;
754
787
  }
755
788
  export async function resolveAbsoluteGitDir(cwd) {
756
789
  try {
@@ -1015,22 +1048,74 @@ async function inspectCheckoutContext(cwd, context) {
1015
1048
  }
1016
1049
  }
1017
1050
  function buildPullRequestLookupTargetFromBranchConfig(input) {
1018
- if (!input.branchRemoteName?.startsWith("paseo-pr-")) {
1019
- return { headRef: input.currentBranch };
1020
- }
1021
1051
  const trackedHeadRef = parseBranchMergeHeadRef(input.branchMergeRef);
1022
- if (!trackedHeadRef) {
1052
+ if (!input.branchRemoteName || !trackedHeadRef || trackedHeadRef === input.currentBranch) {
1023
1053
  return { headRef: input.currentBranch };
1024
1054
  }
1025
1055
  const remoteRepo = input.branchRemoteUrl
1026
1056
  ? parseGitHubRepoFromRemote(input.branchRemoteUrl)
1027
1057
  : null;
1028
- const headRepositoryOwner = remoteRepo?.split("/")[0];
1058
+ const originRepo = input.originRemoteUrl
1059
+ ? parseGitHubRepoFromRemote(input.originRemoteUrl)
1060
+ : null;
1061
+ const isSameRepo = Boolean(remoteRepo && originRepo && remoteRepo === originRepo);
1062
+ const headRepositoryOwner = remoteRepo && !isSameRepo ? remoteRepo.split("/")[0] : null;
1063
+ const normalizedBaseRef = input.resolvedBaseRef
1064
+ ? normalizeLocalBranchRefName(input.resolvedBaseRef)
1065
+ : null;
1066
+ if (trackedHeadRef === normalizedBaseRef && !headRepositoryOwner) {
1067
+ return { headRef: input.currentBranch };
1068
+ }
1069
+ if (isSameRepo) {
1070
+ return { headRef: trackedHeadRef };
1071
+ }
1029
1072
  return {
1030
1073
  headRef: trackedHeadRef,
1031
1074
  ...(headRepositoryOwner ? { headRepositoryOwner } : {}),
1032
1075
  };
1033
1076
  }
1077
+ function buildPullRequestLookupTargetFromPushConfig(input) {
1078
+ const pushedHeadRef = parseHeadPushRefspec(input.pushRefspec);
1079
+ if (!input.pushRemoteName || !pushedHeadRef || pushedHeadRef === input.currentBranch) {
1080
+ return null;
1081
+ }
1082
+ const remoteRepo = input.pushRemoteUrl ? parseGitHubRepoFromRemote(input.pushRemoteUrl) : null;
1083
+ const originRepo = input.originRemoteUrl
1084
+ ? parseGitHubRepoFromRemote(input.originRemoteUrl)
1085
+ : null;
1086
+ const isSameRepo = Boolean(remoteRepo && originRepo && remoteRepo === originRepo);
1087
+ const headRepositoryOwner = remoteRepo && !isSameRepo ? remoteRepo.split("/")[0] : null;
1088
+ const normalizedBaseRef = input.resolvedBaseRef
1089
+ ? normalizeLocalBranchRefName(input.resolvedBaseRef)
1090
+ : null;
1091
+ if (pushedHeadRef === normalizedBaseRef && !headRepositoryOwner) {
1092
+ return null;
1093
+ }
1094
+ return {
1095
+ headRef: pushedHeadRef,
1096
+ ...(headRepositoryOwner ? { headRepositoryOwner } : {}),
1097
+ };
1098
+ }
1099
+ async function resolvePullRequestLookupTargetFromPushConfig(cwd, currentBranch, knownOriginRemoteUrl, knownResolvedBaseRef, context) {
1100
+ const pushRemoteName = await getGitConfigValue(cwd, `branch.${currentBranch}.pushRemote`, context);
1101
+ if (!pushRemoteName) {
1102
+ return null;
1103
+ }
1104
+ const [pushRefspec, pushRemoteUrl, originRemoteUrl, resolvedBaseRef] = await Promise.all([
1105
+ getGitConfigValue(cwd, `remote.${pushRemoteName}.push`, context),
1106
+ getGitConfigValue(cwd, `remote.${pushRemoteName}.url`, context),
1107
+ knownOriginRemoteUrl === null ? getGitConfigValue(cwd, "remote.origin.url", context) : null,
1108
+ knownResolvedBaseRef === null ? getResolvedBaseRefForCwd(cwd, context) : null,
1109
+ ]);
1110
+ return buildPullRequestLookupTargetFromPushConfig({
1111
+ currentBranch,
1112
+ pushRemoteName,
1113
+ pushRefspec,
1114
+ pushRemoteUrl,
1115
+ originRemoteUrl: knownOriginRemoteUrl ?? originRemoteUrl,
1116
+ resolvedBaseRef: knownResolvedBaseRef ?? resolvedBaseRef,
1117
+ });
1118
+ }
1034
1119
  export async function getCheckoutSnapshotFacts(cwd, context) {
1035
1120
  if (context?.facts) {
1036
1121
  return context.facts;
@@ -1053,23 +1138,31 @@ export async function getCheckoutSnapshotFacts(cwd, context) {
1053
1138
  let branchRemoteName = null;
1054
1139
  let branchMergeRef = null;
1055
1140
  let branchRemoteUrl = null;
1056
- if (inspected.remoteUrl && inspected.currentBranch) {
1141
+ if (inspected.currentBranch) {
1057
1142
  branchRemoteName = await getGitConfigValue(cwd, `branch.${inspected.currentBranch}.remote`, context);
1058
1143
  if (branchRemoteName) {
1059
- branchMergeRef = await getGitConfigValue(cwd, `branch.${inspected.currentBranch}.merge`, context);
1060
- if (branchRemoteName.startsWith("paseo-pr-")) {
1061
- branchRemoteUrl = await getGitConfigValue(cwd, `remote.${branchRemoteName}.url`, context);
1062
- }
1144
+ [branchMergeRef, branchRemoteUrl] = await Promise.all([
1145
+ getGitConfigValue(cwd, `branch.${inspected.currentBranch}.merge`, context),
1146
+ getGitConfigValue(cwd, `remote.${branchRemoteName}.url`, context),
1147
+ ]);
1063
1148
  }
1064
1149
  }
1065
- const pullRequestLookupTarget = inspected.currentBranch
1150
+ let pullRequestLookupTarget = inspected.currentBranch
1066
1151
  ? buildPullRequestLookupTargetFromBranchConfig({
1067
1152
  currentBranch: inspected.currentBranch,
1068
1153
  branchRemoteName,
1069
1154
  branchMergeRef,
1070
1155
  branchRemoteUrl,
1156
+ originRemoteUrl: inspected.remoteUrl,
1157
+ resolvedBaseRef,
1071
1158
  })
1072
1159
  : null;
1160
+ if (inspected.currentBranch &&
1161
+ pullRequestLookupTarget?.headRef === inspected.currentBranch &&
1162
+ !pullRequestLookupTarget.headRepositoryOwner) {
1163
+ pullRequestLookupTarget =
1164
+ (await resolvePullRequestLookupTargetFromPushConfig(cwd, inspected.currentBranch, inspected.remoteUrl, resolvedBaseRef, context)) ?? pullRequestLookupTarget;
1165
+ }
1073
1166
  return {
1074
1167
  isGit: true,
1075
1168
  worktreeRoot: inspected.worktreeRoot,
@@ -1935,6 +2028,19 @@ export async function pushCurrentBranch(cwd, github) {
1935
2028
  if (!currentBranch || currentBranch === "HEAD") {
1936
2029
  throw new Error("Unable to determine current branch for push");
1937
2030
  }
2031
+ const configuredPushTarget = await getCurrentBranchConfiguredPushTarget(cwd, currentBranch);
2032
+ if (configuredPushTarget) {
2033
+ await runGitCommand(["push", configuredPushTarget.remoteName, `HEAD:refs/heads/${configuredPushTarget.headRef}`], { cwd, timeout: 120000 });
2034
+ await refreshCurrentBranchTrackedRefAfterPush(cwd, currentBranch, configuredPushTarget);
2035
+ github?.invalidate({ cwd });
2036
+ return;
2037
+ }
2038
+ const upstreamTarget = await getCurrentBranchUpstreamPushTarget(cwd, currentBranch);
2039
+ if (upstreamTarget) {
2040
+ await runGitCommand(["push", "-u", upstreamTarget.remoteName, `HEAD:refs/heads/${upstreamTarget.headRef}`], { cwd, timeout: 120000 });
2041
+ github?.invalidate({ cwd });
2042
+ return;
2043
+ }
1938
2044
  const hasRemote = await hasOriginRemote(cwd);
1939
2045
  if (!hasRemote) {
1940
2046
  throw new Error("Remote 'origin' is not configured.");
@@ -1942,6 +2048,78 @@ export async function pushCurrentBranch(cwd, github) {
1942
2048
  await runGitCommand(["push", "-u", "origin", currentBranch], { cwd, timeout: 120000 });
1943
2049
  github?.invalidate({ cwd });
1944
2050
  }
2051
+ async function getCurrentBranchConfiguredPushTarget(cwd, currentBranch) {
2052
+ const remoteName = await getGitConfigValue(cwd, `branch.${currentBranch}.pushRemote`);
2053
+ const pushRefspec = remoteName ? await getGitConfigValue(cwd, `remote.${remoteName}.push`) : null;
2054
+ const headRef = parseHeadPushRefspec(pushRefspec);
2055
+ if (!remoteName || !headRef) {
2056
+ return null;
2057
+ }
2058
+ const remoteUrl = await getGitConfigValue(cwd, `remote.${remoteName}.url`);
2059
+ return remoteUrl ? { remoteName, headRef } : null;
2060
+ }
2061
+ async function refreshCurrentBranchTrackedRefAfterPush(cwd, currentBranch, pushedTarget) {
2062
+ const trackingRemoteName = await getGitConfigValue(cwd, `branch.${currentBranch}.remote`);
2063
+ const trackingMergeRef = await getGitConfigValue(cwd, `branch.${currentBranch}.merge`);
2064
+ const trackingHeadRef = parseBranchMergeHeadRef(trackingMergeRef);
2065
+ if (!trackingRemoteName && !trackingMergeRef) {
2066
+ const updated = await updateRemoteTrackingRef(cwd, pushedTarget.remoteName, pushedTarget.headRef);
2067
+ if (!updated) {
2068
+ return;
2069
+ }
2070
+ await runGitCommand(["config", `branch.${currentBranch}.remote`, pushedTarget.remoteName], {
2071
+ cwd,
2072
+ });
2073
+ await runGitCommand(["config", `branch.${currentBranch}.merge`, `refs/heads/${pushedTarget.headRef}`], {
2074
+ cwd,
2075
+ });
2076
+ return;
2077
+ }
2078
+ if (!trackingRemoteName || trackingHeadRef !== pushedTarget.headRef) {
2079
+ return;
2080
+ }
2081
+ const [trackingRemotePushUrl, pushedRemotePushUrl] = await Promise.all([
2082
+ getGitRemotePushUrl(cwd, trackingRemoteName),
2083
+ getGitRemotePushUrl(cwd, pushedTarget.remoteName),
2084
+ ]);
2085
+ if (!trackingRemotePushUrl || trackingRemotePushUrl !== pushedRemotePushUrl) {
2086
+ return;
2087
+ }
2088
+ await updateRemoteTrackingRef(cwd, trackingRemoteName, trackingHeadRef);
2089
+ }
2090
+ async function updateRemoteTrackingRef(cwd, remoteName, headRef) {
2091
+ const trackingRef = `refs/remotes/${remoteName}/${headRef}`;
2092
+ const checkRef = await runGitCommand(["check-ref-format", trackingRef], {
2093
+ cwd,
2094
+ acceptExitCodes: [0, 1],
2095
+ });
2096
+ if (checkRef.exitCode !== 0) {
2097
+ return false;
2098
+ }
2099
+ await runGitCommand(["update-ref", trackingRef, "HEAD"], { cwd, timeout: 120000 });
2100
+ return true;
2101
+ }
2102
+ async function getCurrentBranchUpstreamPushTarget(cwd, currentBranch) {
2103
+ const remoteName = await getGitConfigValue(cwd, `branch.${currentBranch}.remote`);
2104
+ const mergeRef = remoteName
2105
+ ? await getGitConfigValue(cwd, `branch.${currentBranch}.merge`)
2106
+ : null;
2107
+ const headRef = parseBranchMergeHeadRef(mergeRef);
2108
+ if (!remoteName || !headRef) {
2109
+ return null;
2110
+ }
2111
+ const remoteUrl = await getGitConfigValue(cwd, `remote.${remoteName}.url`);
2112
+ return remoteUrl ? { remoteName, headRef } : null;
2113
+ }
2114
+ function parseHeadPushRefspec(refspec) {
2115
+ const prefix = "HEAD:refs/heads/";
2116
+ const normalized = refspec?.trim().replace(/^\+/, "");
2117
+ if (!normalized?.startsWith(prefix)) {
2118
+ return null;
2119
+ }
2120
+ const headRef = normalized.slice(prefix.length).trim();
2121
+ return headRef.length > 0 ? headRef : null;
2122
+ }
1945
2123
  export async function createPullRequest(cwd, options, github = createGitHubService(), context) {
1946
2124
  await requireGitRepo(cwd);
1947
2125
  const repo = await resolveGitHubRepo(cwd);
@@ -1,5 +1,6 @@
1
1
  import { readdir, realpath, stat } from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { isPathInsideRoot } from "./path.js";
3
4
  const DEFAULT_LIMIT = 30;
4
5
  const MAX_LIMIT = 100;
5
6
  const DEFAULT_MAX_DEPTH = 12;
@@ -558,10 +559,6 @@ function normalizeRelativePath(homeRoot, absolutePath) {
558
559
  }
559
560
  return relative.split(path.sep).join("/");
560
561
  }
561
- function isPathInsideRoot(root, target) {
562
- const relative = path.relative(root, target);
563
- return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
564
- }
565
562
  function normalizeQueryParts(query, homeRoot) {
566
563
  const typedQuery = query.trim().replace(/\\/g, "/");
567
564
  let normalized = typedQuery;
@@ -13,4 +13,6 @@ export declare function expandTilde(path: string): string;
13
13
  export declare function areEquivalentPaths(left: string, right: string): boolean;
14
14
  export declare function createPathEquivalenceMatcher(target: string): (candidate: string) => boolean;
15
15
  export declare function createRealpathAwarePathMatcher(target: string): (candidate: string) => boolean;
16
+ export declare function isPathInsideRoot(root: string, candidate: string): boolean;
17
+ export declare function isRealpathInsideRoot(root: string, candidate: string): boolean;
16
18
  //# sourceMappingURL=path.d.ts.map
@@ -46,6 +46,19 @@ export function createRealpathAwarePathMatcher(target) {
46
46
  return candidateVariants.some((variant) => targetMatchers.some((matches) => matches(variant)));
47
47
  };
48
48
  }
49
+ export function isPathInsideRoot(root, candidate) {
50
+ const compareAsWindows = shouldCompareAsWindows(root, candidate);
51
+ const platformPath = compareAsWindows ? nodePath.win32 : nodePath.posix;
52
+ const normalizedRoot = normalizePathForComparison(root, compareAsWindows);
53
+ const normalizedCandidate = normalizePathForComparison(candidate, compareAsWindows);
54
+ const relative = platformPath.relative(normalizedRoot, normalizedCandidate);
55
+ return relative === "" || (!relative.startsWith("..") && !platformPath.isAbsolute(relative));
56
+ }
57
+ export function isRealpathInsideRoot(root, candidate) {
58
+ const rootVariants = collectPathVariants(root);
59
+ const candidateVariants = collectPathVariants(candidate);
60
+ return rootVariants.some((rootVariant) => candidateVariants.some((candidateVariant) => isPathInsideRoot(rootVariant, candidateVariant)));
61
+ }
49
62
  function collectPathVariants(value) {
50
63
  const variants = new Set([value]);
51
64
  for (const realpath of resolveRealpathVariants(value)) {
@@ -101,6 +101,7 @@ export type WorktreeSource = {
101
101
  baseRefName: string;
102
102
  localBranchName?: string;
103
103
  pushRemoteUrl?: string;
104
+ trackOriginHead?: boolean;
104
105
  };
105
106
  export interface CreateWorktreeOptions {
106
107
  cwd: string;