@sireai/optimus 0.1.8 → 0.1.10

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 (106) hide show
  1. package/README.md +2 -1
  2. package/dist/cli/optimus.js +145 -81
  3. package/dist/cli/optimus.js.map +1 -1
  4. package/dist/cli/self-update.js +21 -2
  5. package/dist/cli/self-update.js.map +1 -1
  6. package/dist/config/load-config.js +3 -0
  7. package/dist/config/load-config.js.map +1 -1
  8. package/dist/integrations/feishu/feishu-auth-config.d.ts +7 -0
  9. package/dist/integrations/feishu/feishu-auth-config.js +37 -0
  10. package/dist/integrations/feishu/feishu-auth-config.js.map +1 -0
  11. package/dist/integrations/feishu/feishu-auth-service.d.ts +71 -0
  12. package/dist/integrations/feishu/feishu-auth-service.js +399 -0
  13. package/dist/integrations/feishu/feishu-auth-service.js.map +1 -0
  14. package/dist/integrations/feishu/feishu-auth-store.d.ts +29 -0
  15. package/dist/integrations/feishu/feishu-auth-store.js +113 -0
  16. package/dist/integrations/feishu/feishu-auth-store.js.map +1 -0
  17. package/dist/integrations/feishu/feishu-client.d.ts +52 -0
  18. package/dist/integrations/feishu/feishu-client.js +217 -0
  19. package/dist/integrations/feishu/feishu-client.js.map +1 -0
  20. package/dist/integrations/feishu/feishu-doc-service.d.ts +52 -0
  21. package/dist/integrations/feishu/feishu-doc-service.js +323 -0
  22. package/dist/integrations/feishu/feishu-doc-service.js.map +1 -0
  23. package/dist/integrations/feishu/feishu-token-store.d.ts +17 -0
  24. package/dist/integrations/feishu/feishu-token-store.js +34 -0
  25. package/dist/integrations/feishu/feishu-token-store.js.map +1 -0
  26. package/dist/integrations/feishu/feishu-user-service.d.ts +14 -0
  27. package/dist/integrations/feishu/feishu-user-service.js +60 -0
  28. package/dist/integrations/feishu/feishu-user-service.js.map +1 -0
  29. package/dist/integrations/jira/jira-auth-refresh.d.ts +12 -1
  30. package/dist/integrations/jira/jira-auth-refresh.js +76 -0
  31. package/dist/integrations/jira/jira-auth-refresh.js.map +1 -1
  32. package/dist/integrations/jira/jira-cli.js +25 -11
  33. package/dist/integrations/jira/jira-cli.js.map +1 -1
  34. package/dist/integrations/jira/jira-client.d.ts +26 -0
  35. package/dist/integrations/jira/jira-client.js +111 -0
  36. package/dist/integrations/jira/jira-client.js.map +1 -1
  37. package/dist/integrations/jira/jira-submit.d.ts +5 -1
  38. package/dist/integrations/jira/jira-submit.js +119 -12
  39. package/dist/integrations/jira/jira-submit.js.map +1 -1
  40. package/dist/problem-solving-core/codex/codex-runner.d.ts +2 -0
  41. package/dist/problem-solving-core/codex/codex-runner.js +78 -0
  42. package/dist/problem-solving-core/codex/codex-runner.js.map +1 -1
  43. package/dist/problem-solving-core/codex/evolution-skill-guard.js +0 -2
  44. package/dist/problem-solving-core/codex/evolution-skill-guard.js.map +1 -1
  45. package/dist/task-environment/delivery/commit-message/bugfix-commit-message-template.js +4 -1
  46. package/dist/task-environment/delivery/commit-message/bugfix-commit-message-template.js.map +1 -1
  47. package/dist/task-environment/delivery/feishu-analysis-doc-service.d.ts +7 -25
  48. package/dist/task-environment/delivery/feishu-analysis-doc-service.js +35 -336
  49. package/dist/task-environment/delivery/feishu-analysis-doc-service.js.map +1 -1
  50. package/dist/task-environment/delivery/feishu-card-renderer.js +2 -2
  51. package/dist/task-environment/delivery/feishu-card-renderer.js.map +1 -1
  52. package/dist/task-environment/delivery/feishu-content/feishu-content-renderer.d.ts +7 -1
  53. package/dist/task-environment/delivery/feishu-content/feishu-content-renderer.js +51 -2
  54. package/dist/task-environment/delivery/feishu-content/feishu-content-renderer.js.map +1 -1
  55. package/dist/task-environment/delivery/feishu-notifier.js +7 -1
  56. package/dist/task-environment/delivery/feishu-notifier.js.map +1 -1
  57. package/dist/task-environment/delivery/feishu-templates/analysis-message-template.js +1 -1
  58. package/dist/task-environment/delivery/feishu-templates/analysis-message-template.js.map +1 -1
  59. package/dist/task-environment/delivery/feishu-templates/bugfix-message-template.js +27 -4
  60. package/dist/task-environment/delivery/feishu-templates/bugfix-message-template.js.map +1 -1
  61. package/dist/task-environment/delivery/feishu-templates/default-message-template.js +1 -1
  62. package/dist/task-environment/delivery/feishu-templates/default-message-template.js.map +1 -1
  63. package/dist/task-environment/delivery/feishu-templates/patch-message-template.js +27 -4
  64. package/dist/task-environment/delivery/feishu-templates/patch-message-template.js.map +1 -1
  65. package/dist/task-environment/delivery/feishu-templates/sentry-bugfix-message-template.js +27 -4
  66. package/dist/task-environment/delivery/feishu-templates/sentry-bugfix-message-template.js.map +1 -1
  67. package/dist/task-environment/delivery/feishu-templates/template-types.d.ts +7 -1
  68. package/dist/task-environment/delivery/sentry-feishu-card-renderer.js +1 -1
  69. package/dist/task-environment/delivery/sentry-feishu-card-renderer.js.map +1 -1
  70. package/dist/task-environment/delivery/task-delivery-service.d.ts +2 -0
  71. package/dist/task-environment/delivery/task-delivery-service.js +178 -6
  72. package/dist/task-environment/delivery/task-delivery-service.js.map +1 -1
  73. package/dist/task-environment/delivery/task-publication-service.d.ts +29 -2
  74. package/dist/task-environment/delivery/task-publication-service.js +139 -13
  75. package/dist/task-environment/delivery/task-publication-service.js.map +1 -1
  76. package/dist/task-environment/evidence/evidence-preparation-service.d.ts +36 -0
  77. package/dist/task-environment/evidence/evidence-preparation-service.js +341 -0
  78. package/dist/task-environment/evidence/evidence-preparation-service.js.map +1 -0
  79. package/dist/task-environment/execution-addresses.d.ts +8 -0
  80. package/dist/task-environment/execution-addresses.js +8 -0
  81. package/dist/task-environment/execution-addresses.js.map +1 -1
  82. package/dist/task-environment/intake/manual-problem-intake.js +15 -0
  83. package/dist/task-environment/intake/manual-problem-intake.js.map +1 -1
  84. package/dist/task-environment/intake/triage-rejection-feedback-service.d.ts +12 -0
  85. package/dist/task-environment/intake/triage-rejection-feedback-service.js +64 -11
  86. package/dist/task-environment/intake/triage-rejection-feedback-service.js.map +1 -1
  87. package/dist/task-environment/observability/logger.js +24 -0
  88. package/dist/task-environment/observability/logger.js.map +1 -1
  89. package/dist/task-environment/orchestration/execution-context-assembler.d.ts +19 -0
  90. package/dist/task-environment/orchestration/execution-context-assembler.js +422 -1
  91. package/dist/task-environment/orchestration/execution-context-assembler.js.map +1 -1
  92. package/dist/task-environment/orchestration/task-orchestrator.d.ts +3 -0
  93. package/dist/task-environment/orchestration/task-orchestrator.js +135 -6
  94. package/dist/task-environment/orchestration/task-orchestrator.js.map +1 -1
  95. package/dist/task-environment/orchestration/triage-runner.d.ts +2 -0
  96. package/dist/task-environment/orchestration/triage-runner.js +27 -1
  97. package/dist/task-environment/orchestration/triage-runner.js.map +1 -1
  98. package/dist/task-environment/runtime/optimus-runtime.js +4 -3
  99. package/dist/task-environment/runtime/optimus-runtime.js.map +1 -1
  100. package/dist/types.d.ts +22 -0
  101. package/embedded-skills/shared/video-keyframe-analyzer/SKILL.md +86 -0
  102. package/embedded-skills/shared/video-keyframe-analyzer/scripts/extract-keyframes.mjs +614 -0
  103. package/embedded-skills/shared/{repo-inspection → video-keyframe-analyzer}/skill.json +1 -1
  104. package/package.json +7 -3
  105. package/task-harnesses/bugfix/STANDARD.md +104 -31
  106. package/embedded-skills/shared/repo-inspection/SKILL.md +0 -9
@@ -0,0 +1,399 @@
1
+ import { execFileSync, spawn } from "node:child_process";
2
+ import { platform } from "node:os";
3
+ import { resolveFeishuAuthAppConfig } from "./feishu-auth-config.js";
4
+ import { FileFeishuAuthStore, isFeishuAccessTokenExpired, isFeishuRefreshTokenExpired, readFeishuAuthRecordSync } from "./feishu-auth-store.js";
5
+ const FEISHU_AUTH_SCOPES = [
6
+ "docx:document",
7
+ "docx:document:create",
8
+ "docx:document.block:convert",
9
+ "docs:document.media:upload",
10
+ "wiki:node:read",
11
+ "wiki:wiki",
12
+ "drive:drive",
13
+ "bitable:app",
14
+ "board:whiteboard:node:create",
15
+ "board:whiteboard:node:delete",
16
+ "board:whiteboard:node:update",
17
+ "board:whiteboard:node:read",
18
+ "slides:presentation:read",
19
+ "slides:presentation:create",
20
+ "slides:presentation:update",
21
+ "slides:presentation:write_only",
22
+ "calendar:calendar",
23
+ "task:task:read",
24
+ "task:task:write",
25
+ "task:tasklist:read",
26
+ "task:tasklist:write",
27
+ "contact:contact.base:readonly",
28
+ "contact:user.base:readonly",
29
+ "contact:user:search",
30
+ "offline_access"
31
+ ].join(" ");
32
+ const DEFAULT_INTERACTIVE_RELOGIN_TIMEOUT_MS = 90_000;
33
+ const DEFAULT_INTERACTIVE_RELOGIN_COOLDOWN_MS = 5 * 60_000;
34
+ let sharedReloginPromise;
35
+ let lastReloginFailureAt = 0;
36
+ let lastReloginFailureReason;
37
+ export class FeishuAuthService {
38
+ env;
39
+ store;
40
+ fetchImpl;
41
+ openExternal;
42
+ interactiveReloginTimeoutMs;
43
+ interactiveReloginCooldownMs;
44
+ onEvent;
45
+ constructor(options = {}) {
46
+ this.env = options.env ?? process.env;
47
+ this.store = options.store ?? new FileFeishuAuthStore();
48
+ this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
49
+ this.openExternal = options.openExternal ?? openInBrowser;
50
+ this.interactiveReloginTimeoutMs = Math.max(1_000, options.interactiveReloginTimeoutMs ?? DEFAULT_INTERACTIVE_RELOGIN_TIMEOUT_MS);
51
+ this.interactiveReloginCooldownMs = Math.max(0, options.interactiveReloginCooldownMs ?? DEFAULT_INTERACTIVE_RELOGIN_COOLDOWN_MS);
52
+ this.onEvent = options.onEvent;
53
+ }
54
+ readStatus() {
55
+ const config = resolveFeishuAuthAppConfig(this.env);
56
+ const record = this.store.readSync?.() ?? readFeishuAuthRecordSync();
57
+ if (!record) {
58
+ return {
59
+ authenticated: false,
60
+ accessTokenExpired: false,
61
+ refreshTokenExpired: false,
62
+ baseUrl: config.baseUrl
63
+ };
64
+ }
65
+ const accessTokenExpired = isFeishuAccessTokenExpired(record);
66
+ const refreshTokenExpired = isFeishuRefreshTokenExpired(record);
67
+ return {
68
+ authenticated: !refreshTokenExpired,
69
+ accessTokenExpired,
70
+ refreshTokenExpired,
71
+ baseUrl: record.baseUrl?.trim() || config.baseUrl,
72
+ accessTokenExpiresAt: new Date(record.expiresAtMs).toISOString(),
73
+ refreshTokenExpiresAt: new Date(record.refreshExpiresAtMs).toISOString(),
74
+ ...(record.openId ? { openId: record.openId } : {}),
75
+ ...(record.userId ? { userId: record.userId } : {})
76
+ };
77
+ }
78
+ async login(options = {}) {
79
+ const config = resolveFeishuAuthAppConfig(this.env);
80
+ const deviceAuth = await this.requestDeviceAuthorization(config);
81
+ options.onPrompt?.({
82
+ verificationUrl: deviceAuth.verificationUrl,
83
+ expiresInSeconds: deviceAuth.expiresInSeconds
84
+ });
85
+ this.openExternal(deviceAuth.verificationUrl);
86
+ const tokenPayload = await this.pollDeviceToken(config, deviceAuth.deviceCode, deviceAuth.intervalSeconds, deviceAuth.expiresInSeconds, options.timeoutMs);
87
+ const record = await this.buildRecord(config.baseUrl, tokenPayload);
88
+ await this.store.write(record);
89
+ return {
90
+ ...record,
91
+ verificationUrl: deviceAuth.verificationUrl
92
+ };
93
+ }
94
+ async logout() {
95
+ await this.store.clear();
96
+ }
97
+ async getValidAccessToken() {
98
+ const stored = await this.store.read();
99
+ if (!stored) {
100
+ throw new Error("Feishu auth is missing. Run `optimus feishu auth login`.");
101
+ }
102
+ if (!isFeishuAccessTokenExpired(stored)) {
103
+ return { accessToken: stored.accessToken, record: stored };
104
+ }
105
+ if (isFeishuRefreshTokenExpired(stored)) {
106
+ return await this.reloginAndReadToken("refresh_token_expired");
107
+ }
108
+ try {
109
+ const refreshed = await this.refreshAccessToken(stored);
110
+ await this.store.write(refreshed);
111
+ return { accessToken: refreshed.accessToken, record: refreshed };
112
+ }
113
+ catch (error) {
114
+ if (!this.shouldAttemptInteractiveRelogin(error)) {
115
+ throw error;
116
+ }
117
+ return await this.reloginAndReadToken("refresh_token_refresh_failed");
118
+ }
119
+ }
120
+ async recoverExpiredAuth(reason) {
121
+ const stored = await this.store.read();
122
+ if (!stored) {
123
+ return undefined;
124
+ }
125
+ if (!isFeishuRefreshTokenExpired(stored)) {
126
+ try {
127
+ const refreshed = await this.refreshAccessToken(stored);
128
+ await this.store.write(refreshed);
129
+ return {
130
+ accessToken: refreshed.accessToken,
131
+ record: refreshed
132
+ };
133
+ }
134
+ catch (error) {
135
+ if (!this.shouldAttemptInteractiveRelogin(error)) {
136
+ throw error;
137
+ }
138
+ }
139
+ }
140
+ return await this.reloginAndReadToken(reason);
141
+ }
142
+ async requestDeviceAuthorization(config) {
143
+ const response = await this.fetchImpl(`${config.accountsBaseUrl}/oauth/v1/device_authorization`, {
144
+ method: "POST",
145
+ headers: {
146
+ "content-type": "application/x-www-form-urlencoded",
147
+ authorization: `Basic ${Buffer.from(`${config.appId}:${config.appSecret}`).toString("base64")}`
148
+ },
149
+ body: new URLSearchParams({
150
+ client_id: config.appId,
151
+ scope: FEISHU_AUTH_SCOPES
152
+ }).toString()
153
+ });
154
+ const payload = await readJson(response);
155
+ if (!response.ok || payload.error) {
156
+ throw new Error(`Feishu device authorization failed: ${payload.error_description || payload.error || response.statusText}`);
157
+ }
158
+ return {
159
+ deviceCode: String(payload.device_code || ""),
160
+ verificationUrl: String(payload.verification_uri_complete || payload.verification_uri || ""),
161
+ expiresInSeconds: Number(payload.expires_in || 600),
162
+ intervalSeconds: Number(payload.interval || 5)
163
+ };
164
+ }
165
+ async pollDeviceToken(config, deviceCode, initialIntervalSeconds, expiresInSeconds, timeoutMs) {
166
+ const hardDeadline = Date.now() + expiresInSeconds * 1000;
167
+ const interactiveDeadline = timeoutMs ? Date.now() + timeoutMs : Number.POSITIVE_INFINITY;
168
+ const deadline = Math.min(hardDeadline, interactiveDeadline);
169
+ let intervalSeconds = initialIntervalSeconds;
170
+ while (Date.now() < deadline) {
171
+ await sleep(intervalSeconds * 1000);
172
+ const payload = await this.postToken(config, {
173
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
174
+ device_code: deviceCode,
175
+ client_id: config.appId,
176
+ client_secret: config.appSecret
177
+ });
178
+ if (typeof payload.access_token === "string" && payload.access_token.trim()) {
179
+ return payload;
180
+ }
181
+ switch (payload.error) {
182
+ case "authorization_pending":
183
+ break;
184
+ case "slow_down":
185
+ intervalSeconds = Math.min(intervalSeconds + 5, 60);
186
+ break;
187
+ case "access_denied":
188
+ throw new Error("Feishu interactive re-login was declined.");
189
+ default:
190
+ throw new Error(`Feishu authorization failed: ${payload.error_description || payload.error || "unknown_error"}`);
191
+ }
192
+ }
193
+ if (deadline < hardDeadline) {
194
+ throw new Error("Feishu interactive re-login timed out.");
195
+ }
196
+ throw new Error("Feishu authorization timed out. Please retry `optimus feishu auth login`.");
197
+ }
198
+ async refreshAccessToken(stored) {
199
+ const config = resolveFeishuAuthAppConfig(this.env);
200
+ const payload = await this.postToken(config, {
201
+ grant_type: "refresh_token",
202
+ refresh_token: stored.refreshToken,
203
+ client_id: config.appId,
204
+ client_secret: config.appSecret
205
+ });
206
+ if (typeof payload.access_token !== "string" || !payload.access_token.trim()) {
207
+ throw new Error("Feishu token refresh failed. Run `optimus feishu auth login` again.");
208
+ }
209
+ const refreshed = await this.buildRecord(stored.baseUrl?.trim() || config.baseUrl, payload, stored);
210
+ return refreshed;
211
+ }
212
+ async postToken(config, body) {
213
+ const response = await this.fetchImpl(`${config.baseUrl}/open-apis/authen/v2/oauth/token`, {
214
+ method: "POST",
215
+ headers: {
216
+ "content-type": "application/x-www-form-urlencoded"
217
+ },
218
+ body: new URLSearchParams(body).toString()
219
+ });
220
+ return await readJson(response);
221
+ }
222
+ async reloginAndReadToken(reason) {
223
+ const result = await this.waitForInteractiveRelogin(reason);
224
+ return {
225
+ accessToken: result.accessToken,
226
+ record: result
227
+ };
228
+ }
229
+ async waitForInteractiveRelogin(reason) {
230
+ if (sharedReloginPromise) {
231
+ this.emit({
232
+ type: "relogin_waiting",
233
+ reason,
234
+ timeoutMs: this.interactiveReloginTimeoutMs
235
+ });
236
+ return await sharedReloginPromise;
237
+ }
238
+ if (this.interactiveReloginCooldownMs > 0 && Date.now() - lastReloginFailureAt < this.interactiveReloginCooldownMs) {
239
+ throw new Error(lastReloginFailureReason ?? "Feishu interactive re-login is cooling down after a recent failure.");
240
+ }
241
+ this.emit({
242
+ type: "relogin_required",
243
+ reason,
244
+ timeoutMs: this.interactiveReloginTimeoutMs
245
+ });
246
+ const promise = (async () => {
247
+ this.emit({
248
+ type: "relogin_started",
249
+ reason,
250
+ timeoutMs: this.interactiveReloginTimeoutMs
251
+ });
252
+ const result = await this.login({
253
+ timeoutMs: this.interactiveReloginTimeoutMs,
254
+ onPrompt: ({ verificationUrl, expiresInSeconds }) => {
255
+ this.emit({
256
+ type: "relogin_waiting",
257
+ reason,
258
+ timeoutMs: this.interactiveReloginTimeoutMs,
259
+ verificationUrl,
260
+ expiresInSeconds
261
+ });
262
+ }
263
+ });
264
+ this.emit({
265
+ type: "relogin_succeeded",
266
+ reason,
267
+ timeoutMs: this.interactiveReloginTimeoutMs,
268
+ verificationUrl: result.verificationUrl,
269
+ ...(result.userId ? { userId: result.userId } : {}),
270
+ ...(result.openId ? { openId: result.openId } : {})
271
+ });
272
+ return result;
273
+ })();
274
+ sharedReloginPromise = promise;
275
+ try {
276
+ const result = await promise;
277
+ lastReloginFailureAt = 0;
278
+ lastReloginFailureReason = undefined;
279
+ return result;
280
+ }
281
+ catch (error) {
282
+ const message = error instanceof Error ? error.message : String(error);
283
+ lastReloginFailureAt = Date.now();
284
+ lastReloginFailureReason = message;
285
+ this.emit({
286
+ type: classifyReloginFailure(message),
287
+ reason,
288
+ timeoutMs: this.interactiveReloginTimeoutMs,
289
+ error: message
290
+ });
291
+ throw error;
292
+ }
293
+ finally {
294
+ if (sharedReloginPromise === promise) {
295
+ sharedReloginPromise = undefined;
296
+ }
297
+ }
298
+ }
299
+ shouldAttemptInteractiveRelogin(error) {
300
+ const message = error instanceof Error ? error.message : String(error);
301
+ return /token refresh failed|run `optimus feishu auth login` again|invalid_grant|access_denied|refresh_token/iu.test(message);
302
+ }
303
+ emit(event) {
304
+ try {
305
+ this.onEvent?.(event);
306
+ }
307
+ catch {
308
+ // Logging hooks are best-effort.
309
+ }
310
+ }
311
+ async buildRecord(baseUrl, payload, previous) {
312
+ const now = Date.now();
313
+ const accessToken = String(payload.access_token || previous?.accessToken || "");
314
+ const refreshToken = String(payload.refresh_token || previous?.refreshToken || "");
315
+ const expiresAtMs = now + Number(payload.expires_in || 7200) * 1000;
316
+ const refreshExpiresAtMs = now + Number(payload.refresh_token_expires_in || 2_592_000) * 1000;
317
+ const userInfo = await this.fetchUserInfo(baseUrl, accessToken).catch(() => undefined);
318
+ const openId = userInfo?.openId ?? previous?.openId;
319
+ const tenantKey = userInfo?.tenantKey ?? previous?.tenantKey;
320
+ const userId = userInfo?.userId ?? previous?.userId;
321
+ return {
322
+ accessToken,
323
+ refreshToken,
324
+ expiresAtMs,
325
+ refreshExpiresAtMs,
326
+ baseUrl,
327
+ ...(openId ? { openId } : {}),
328
+ ...(tenantKey ? { tenantKey } : {}),
329
+ ...(userId ? { userId } : {})
330
+ };
331
+ }
332
+ async fetchUserInfo(baseUrl, accessToken) {
333
+ const response = await this.fetchImpl(`${baseUrl}/open-apis/authen/v1/user_info`, {
334
+ method: "GET",
335
+ headers: {
336
+ authorization: `Bearer ${accessToken}`
337
+ }
338
+ });
339
+ const payload = await readJson(response);
340
+ const data = payload.data && typeof payload.data === "object" ? payload.data : payload;
341
+ return {
342
+ ...(typeof data.open_id === "string" && data.open_id.trim() ? { openId: data.open_id.trim() } : {}),
343
+ ...(typeof data.tenant_key === "string" && data.tenant_key.trim() ? { tenantKey: data.tenant_key.trim() } : {}),
344
+ ...(typeof data.user_id === "string" && data.user_id.trim() ? { userId: data.user_id.trim() } : {})
345
+ };
346
+ }
347
+ }
348
+ async function readJson(response) {
349
+ const text = await response.text();
350
+ if (!text.trim()) {
351
+ return {};
352
+ }
353
+ try {
354
+ return JSON.parse(text);
355
+ }
356
+ catch {
357
+ return { raw: text };
358
+ }
359
+ }
360
+ function openInBrowser(url) {
361
+ try {
362
+ let child;
363
+ if (platform() === "darwin") {
364
+ child = spawn("open", [url], { detached: true, stdio: "ignore" });
365
+ }
366
+ else if (platform() === "win32") {
367
+ child = spawn(`start "" "${url}"`, { shell: true, detached: true, stdio: "ignore" });
368
+ }
369
+ else {
370
+ let command = "xdg-open";
371
+ try {
372
+ execFileSync("which", ["wslview"], { stdio: "ignore" });
373
+ command = "wslview";
374
+ }
375
+ catch {
376
+ // Fall back to xdg-open.
377
+ }
378
+ child = spawn(command, [url], { detached: true, stdio: "ignore" });
379
+ }
380
+ child.on("error", () => { });
381
+ child.unref();
382
+ }
383
+ catch {
384
+ // Best-effort.
385
+ }
386
+ }
387
+ function sleep(timeoutMs) {
388
+ return new Promise((resolve) => setTimeout(resolve, timeoutMs));
389
+ }
390
+ function classifyReloginFailure(message) {
391
+ if (/declined|access_denied/iu.test(message)) {
392
+ return "relogin_declined";
393
+ }
394
+ if (/timed out/iu.test(message)) {
395
+ return "relogin_timed_out";
396
+ }
397
+ return "relogin_failed";
398
+ }
399
+ //# sourceMappingURL=feishu-auth-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-auth-service.js","sourceRoot":"","sources":["../../../src/integrations/feishu/feishu-auth-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface FeishuAuthRecord {
2
+ accessToken: string;
3
+ refreshToken: string;
4
+ expiresAtMs: number;
5
+ refreshExpiresAtMs: number;
6
+ openId?: string;
7
+ tenantKey?: string;
8
+ userId?: string;
9
+ baseUrl?: string;
10
+ }
11
+ export interface FeishuAuthStore {
12
+ read(): Promise<FeishuAuthRecord | undefined>;
13
+ readSync?(): FeishuAuthRecord | undefined;
14
+ write(record: FeishuAuthRecord): Promise<void>;
15
+ clear(): Promise<void>;
16
+ }
17
+ export declare function resolveDefaultFeishuAuthPath(): string;
18
+ export declare class FileFeishuAuthStore implements FeishuAuthStore {
19
+ private readonly filePath;
20
+ constructor(filePath?: string);
21
+ read(): Promise<FeishuAuthRecord | undefined>;
22
+ readSync(): FeishuAuthRecord | undefined;
23
+ write(record: FeishuAuthRecord): Promise<void>;
24
+ clear(): Promise<void>;
25
+ }
26
+ export declare function readFeishuAuthRecordSync(filePath?: string): FeishuAuthRecord | undefined;
27
+ export declare function writeFeishuAuthRecordSync(record: FeishuAuthRecord, filePath?: string): void;
28
+ export declare function isFeishuAccessTokenExpired(record: Pick<FeishuAuthRecord, "expiresAtMs">, nowMs?: number): boolean;
29
+ export declare function isFeishuRefreshTokenExpired(record: Pick<FeishuAuthRecord, "refreshExpiresAtMs">, nowMs?: number): boolean;
@@ -0,0 +1,113 @@
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { resolveOptimusHomeDir } from "../../config/optimus-paths.js";
5
+ export function resolveDefaultFeishuAuthPath() {
6
+ return join(resolveOptimusHomeDir(), "auth", "feishu.json");
7
+ }
8
+ export class FileFeishuAuthStore {
9
+ filePath;
10
+ constructor(filePath = resolveDefaultFeishuAuthPath()) {
11
+ this.filePath = filePath;
12
+ }
13
+ async read() {
14
+ try {
15
+ return normalizeAuthRecord(JSON.parse(await readFile(this.filePath, "utf8")));
16
+ }
17
+ catch {
18
+ return undefined;
19
+ }
20
+ }
21
+ readSync() {
22
+ return readFeishuAuthRecordSync(this.filePath);
23
+ }
24
+ async write(record) {
25
+ await mkdir(dirname(this.filePath), { recursive: true });
26
+ await writeFile(this.filePath, `${JSON.stringify(record, null, 2)}\n`, "utf8");
27
+ try {
28
+ chmodSync(this.filePath, 0o600);
29
+ }
30
+ catch {
31
+ // chmod is best-effort.
32
+ }
33
+ }
34
+ async clear() {
35
+ await rm(this.filePath, { force: true });
36
+ }
37
+ }
38
+ export function readFeishuAuthRecordSync(filePath = resolveDefaultFeishuAuthPath()) {
39
+ if (!existsSync(filePath)) {
40
+ return undefined;
41
+ }
42
+ try {
43
+ return normalizeAuthRecord(JSON.parse(readFileSync(filePath, "utf8")));
44
+ }
45
+ catch {
46
+ return undefined;
47
+ }
48
+ }
49
+ export function writeFeishuAuthRecordSync(record, filePath = resolveDefaultFeishuAuthPath()) {
50
+ mkdirSync(dirname(filePath), { recursive: true });
51
+ writeFileSync(filePath, `${JSON.stringify(record, null, 2)}\n`, "utf8");
52
+ try {
53
+ chmodSync(filePath, 0o600);
54
+ }
55
+ catch {
56
+ // chmod is best-effort.
57
+ }
58
+ }
59
+ export function isFeishuAccessTokenExpired(record, nowMs = Date.now()) {
60
+ return nowMs >= record.expiresAtMs - 60_000;
61
+ }
62
+ export function isFeishuRefreshTokenExpired(record, nowMs = Date.now()) {
63
+ return nowMs >= record.refreshExpiresAtMs - 60_000;
64
+ }
65
+ function normalizeAuthRecord(value) {
66
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
67
+ return undefined;
68
+ }
69
+ const record = value;
70
+ const accessToken = readString(record, ["accessToken", "access_token"]);
71
+ const refreshToken = readString(record, ["refreshToken", "refresh_token"]);
72
+ const expiresAtMs = readTimestampMs(record, ["expiresAtMs", "expires_at"], "seconds");
73
+ const refreshExpiresAtMs = readTimestampMs(record, ["refreshExpiresAtMs", "refresh_expires_at"], "seconds");
74
+ if (!accessToken || !refreshToken || !Number.isFinite(expiresAtMs) || !Number.isFinite(refreshExpiresAtMs)) {
75
+ return undefined;
76
+ }
77
+ const openId = readString(record, ["openId", "open_id"]);
78
+ const tenantKey = readString(record, ["tenantKey", "tenant_key"]);
79
+ const userId = readString(record, ["userId", "user_id"]);
80
+ const baseUrl = readString(record, ["baseUrl", "base_url"]);
81
+ return {
82
+ accessToken,
83
+ refreshToken,
84
+ expiresAtMs,
85
+ refreshExpiresAtMs,
86
+ ...(openId ? { openId } : {}),
87
+ ...(tenantKey ? { tenantKey } : {}),
88
+ ...(userId ? { userId } : {}),
89
+ ...(baseUrl ? { baseUrl } : {})
90
+ };
91
+ }
92
+ function readString(record, keys) {
93
+ for (const key of keys) {
94
+ const raw = record[key];
95
+ if (typeof raw === "string" && raw.trim()) {
96
+ return raw.trim();
97
+ }
98
+ }
99
+ return undefined;
100
+ }
101
+ function readTimestampMs(record, keys, snakeCaseUnit) {
102
+ for (const key of keys) {
103
+ const raw = record[key];
104
+ const parsed = typeof raw === "number" ? raw : typeof raw === "string" ? Number(raw) : Number.NaN;
105
+ if (!Number.isFinite(parsed)) {
106
+ continue;
107
+ }
108
+ const shouldTreatAsSeconds = key.includes("_") && snakeCaseUnit === "seconds";
109
+ return shouldTreatAsSeconds ? parsed * 1000 : parsed;
110
+ }
111
+ return Number.NaN;
112
+ }
113
+ //# sourceMappingURL=feishu-auth-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feishu-auth-store.js","sourceRoot":"","sources":["../../../src/integrations/feishu/feishu-auth-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { OptimusConfig } from "../../types.js";
2
+ import { FeishuAuthService, type FeishuAuthServiceOptions } from "./feishu-auth-service.js";
3
+ import { type FeishuTokenStore } from "./feishu-token-store.js";
4
+ export declare class FeishuIntegrationError extends Error {
5
+ readonly diagnostics: {
6
+ category: "config_missing" | "auth_failed" | "request_failed";
7
+ status?: number;
8
+ code?: number;
9
+ detail?: string;
10
+ };
11
+ constructor(message: string, diagnostics: {
12
+ category: "config_missing" | "auth_failed" | "request_failed";
13
+ status?: number;
14
+ code?: number;
15
+ detail?: string;
16
+ });
17
+ }
18
+ export interface FeishuClientOptions {
19
+ config?: Pick<OptimusConfig, "delivery">;
20
+ env?: NodeJS.ProcessEnv;
21
+ fetchImpl?: typeof globalThis.fetch;
22
+ tokenStore?: FeishuTokenStore;
23
+ authService?: Pick<FeishuAuthService, "getValidAccessToken" | "recoverExpiredAuth" | "readStatus">;
24
+ authServiceOptions?: Omit<FeishuAuthServiceOptions, "env" | "fetchImpl">;
25
+ }
26
+ export declare class FeishuClient {
27
+ private readonly env;
28
+ private readonly fetchImpl;
29
+ private readonly tokenStore;
30
+ private readonly authService;
31
+ private readonly baseUrl;
32
+ private readonly appId;
33
+ private readonly appSecret;
34
+ constructor(options?: FeishuClientOptions);
35
+ isConfigured(): boolean;
36
+ get<T>(path: string, query?: Record<string, string | undefined>): Promise<T>;
37
+ post<T>(path: string, body?: unknown, query?: Record<string, string | undefined>): Promise<T>;
38
+ patch<T>(path: string, body?: unknown, query?: Record<string, string | undefined>): Promise<T>;
39
+ private request;
40
+ private getTenantAccessToken;
41
+ private getAccessToken;
42
+ private buildUrl;
43
+ private readResponsePayload;
44
+ private payloadHasError;
45
+ private extractCode;
46
+ private isAuthExpired;
47
+ private readString;
48
+ private readNumber;
49
+ private readConfiguredValue;
50
+ private normalizeBaseUrl;
51
+ private compact;
52
+ }