@sideboard-ai/core 0.1.202 → 0.1.203

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 (44) hide show
  1. package/dist/{abletime-KGPD3UUJ.js → abletime-JFGZBDHH.js} +4 -2
  2. package/dist/{abletime-345SE3B4.js → abletime-SISJEPJ3.js} +4 -2
  3. package/dist/abletime-oauth-7TD5Z2QV.js +265 -0
  4. package/dist/abletime-oauth-OSQYFB3E.js +40 -0
  5. package/dist/abletime-rest-QPJTDLKX.js +25 -0
  6. package/dist/abletime-rest-ZJGWYALM.js +24 -0
  7. package/dist/{agents-OXX3ONVY.js → agents-3755WYQM.js} +4 -4
  8. package/dist/{agents-573ZDIX6.js → agents-ZMWL43SP.js} +4 -4
  9. package/dist/{app-settings-V6IHESEQ.js → app-settings-LGHMNHSP.js} +1 -1
  10. package/dist/{app-settings-AXCURTZJ.js → app-settings-YEPF46IJ.js} +1 -1
  11. package/dist/{chunk-7NKY2OX7.js → chunk-2DVCCLII.js} +78 -62
  12. package/dist/chunk-3PYH2RLA.js +388 -0
  13. package/dist/{chunk-A2TAKYSG.js → chunk-5IXJTUST.js} +4 -4
  14. package/dist/chunk-6VEIKW5C.js +390 -0
  15. package/dist/chunk-BFEBFGCS.js +250 -0
  16. package/dist/{chunk-STPZQR5B.js → chunk-CMGRV36E.js} +1 -1
  17. package/dist/{chunk-PGQGP4FD.js → chunk-FZ6IBUKY.js} +36 -218
  18. package/dist/{chunk-7AHAABKN.js → chunk-FZYYEMET.js} +36 -228
  19. package/dist/{chunk-54RSAMBH.js → chunk-LCU6GBZP.js} +2 -2
  20. package/dist/chunk-MHPINQKY.js +260 -0
  21. package/dist/chunk-PJHFNFXA.js +243 -0
  22. package/dist/{chunk-CXFW5LIH.js → chunk-QFBBUFD4.js} +38 -3
  23. package/dist/{chunk-RPX6VDW7.js → chunk-QSEF2YVQ.js} +1 -1
  24. package/dist/{chunk-LJHC62LZ.js → chunk-TNDUTGDV.js} +2 -2
  25. package/dist/{chunk-27GGXX27.js → chunk-TZNJKZ2A.js} +82 -66
  26. package/dist/{chunk-NIVF5NDN.js → chunk-X2TFUFIS.js} +4 -4
  27. package/dist/{chunk-ISV5IFH3.js → chunk-X743YN5Y.js} +38 -3
  28. package/dist/{coordinator-prompt-TY5FHAXC.js → coordinator-prompt-2B2JA2IE.js} +3 -3
  29. package/dist/{coordinator-prompt-BH4EHFOO.js → coordinator-prompt-U4PEZDAW.js} +3 -3
  30. package/dist/{global-workspace-NLLAPQJI.js → global-workspace-JPJ3FKKY.js} +3 -3
  31. package/dist/{global-workspace-5AZEEQRU.js → global-workspace-PU7ZS3LS.js} +3 -3
  32. package/dist/index.cjs +912 -142
  33. package/dist/index.d.cts +61 -9
  34. package/dist/index.d.ts +61 -9
  35. package/dist/index.js +63 -18
  36. package/dist/mcp/run-stdio.cjs +843 -114
  37. package/dist/mcp/run-stdio.js +22 -20
  38. package/dist/{orchestrator-JNSQDRZI.js → orchestrator-3A6KUTNI.js} +5 -5
  39. package/dist/{orchestrator-NCYKEI3E.js → orchestrator-Q33M24ZJ.js} +6 -6
  40. package/dist/{workspaces-RP76JH3J.js → workspaces-IMG7ZRUQ.js} +3 -3
  41. package/dist/{workspaces-PEWYWVHZ.js → workspaces-U6P6DB44.js} +3 -3
  42. package/dist/{worktree-ZQEUKSNE.js → worktree-FL3UIUKQ.js} +2 -2
  43. package/dist/{worktree-72TZWUSH.js → worktree-JSCDJPBU.js} +2 -2
  44. package/package.json +1 -1
@@ -0,0 +1,243 @@
1
+ #!/usr/bin/env node
2
+
3
+ import {
4
+ httpFetch
5
+ } from "./chunk-VKQGAWHY.js";
6
+ import {
7
+ getAbleTimeHost,
8
+ isAbleTimeConnected
9
+ } from "./chunk-X743YN5Y.js";
10
+
11
+ // src/integrations/abletime-mcp.ts
12
+ var DEFAULT_ABLETIME_HOST = "https://track.abletime.com";
13
+ var ABLETIME_MCP_PATH = "/api/public/v2/mcp";
14
+ var ABLETIME_MCP_PM_PATH = "/api/public/v2/mcp/pm";
15
+ var MCP_PROTOCOL_VERSION = "2025-03-26";
16
+ var ABLETIME_PM_TOOL_NAMES = [
17
+ "set_task_assignee",
18
+ "set_task_priority",
19
+ "set_task_stage",
20
+ "set_task_dependency",
21
+ "set_task_blocked",
22
+ "set_task_locked",
23
+ "set_task_schedule",
24
+ "clear_task_schedule",
25
+ "archive_task",
26
+ "delete_task"
27
+ ];
28
+ function abletimeToolUsesPm(name) {
29
+ return ABLETIME_PM_TOOL_NAMES.includes(name);
30
+ }
31
+ function normalizeAbleTimeHost(raw) {
32
+ const trimmed = raw?.trim() || DEFAULT_ABLETIME_HOST;
33
+ const withScheme = /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
34
+ return withScheme.replace(/\/+$/, "");
35
+ }
36
+ function abletimeMcpUrl(host, opts) {
37
+ const path = opts?.pm ? ABLETIME_MCP_PM_PATH : ABLETIME_MCP_PATH;
38
+ return `${normalizeAbleTimeHost(host)}${path}`;
39
+ }
40
+ var ABLETIME_PAT_PREFIX = "apt_";
41
+ var ABLETIME_ORG_KEY_PREFIX = "atk_";
42
+ var ORG_KEY_HINT = "AbleTime MCP needs a personal access token (apt_\u2026) from Edit Profile \u2192 API Access, not an organization API key (atk_\u2026) from Settings \u2192 Integrations \u2192 API Keys.";
43
+ var REJECTED_CREDENTIAL_HINT = "AbleTime rejected this credential (unknown, revoked, or expired). Use a personal access token (apt_\u2026) from Edit Profile \u2192 API Access \u2014 organization API keys (atk_\u2026) cannot call MCP. Tokens are shown once; rotating replaces the previous one.";
44
+ var REWRITE_APPLIED = /— Enable Agent access \(MCP\)|— AbleTime MCP needs a personal access token|— AbleTime plan does not include API access|— AbleTime rejected this credential/;
45
+ function normalizeAbleTimeCredential(raw) {
46
+ return raw.trim().replace(/^bearer\s+/i, "").trim();
47
+ }
48
+ function ableTimeCredentialKind(raw) {
49
+ const token = normalizeAbleTimeCredential(raw).toLowerCase();
50
+ if (token.startsWith(ABLETIME_PAT_PREFIX)) return "pat";
51
+ if (token.startsWith(ABLETIME_ORG_KEY_PREFIX)) return "org";
52
+ return "unknown";
53
+ }
54
+ function assertAbleTimeMcpCredential(raw) {
55
+ const token = normalizeAbleTimeCredential(raw);
56
+ if (!token) {
57
+ throw new Error("AbleTime personal access token is required");
58
+ }
59
+ if (ableTimeCredentialKind(token) === "org") {
60
+ throw new Error(ORG_KEY_HINT);
61
+ }
62
+ return token;
63
+ }
64
+ function assertAbleTimeCredential(raw) {
65
+ const token = normalizeAbleTimeCredential(raw);
66
+ if (!token) {
67
+ throw new Error("AbleTime API key or personal access token is required");
68
+ }
69
+ return token;
70
+ }
71
+ function rewriteAbleTimeError(message) {
72
+ if (REWRITE_APPLIED.test(message)) return message;
73
+ if (/INTEGRATION_AGENT_ACCESS_DISABLED/i.test(message)) {
74
+ return `${message} \u2014 Enable Agent access (MCP) in AbleTime Settings \u2192 Integrations \u2192 API Keys.`;
75
+ }
76
+ if (/INTEGRATION_PAT_REQUIRED/i.test(message)) {
77
+ return `${message} \u2014 ${ORG_KEY_HINT}`;
78
+ }
79
+ if (/INTEGRATION_PLAN_REQUIRED/i.test(message)) {
80
+ return `${message} \u2014 AbleTime plan does not include API access.`;
81
+ }
82
+ if (/INTEGRATION_KEY_INVALID|INTEGRATION_KEY_MISSING|401|unauthorized|invalid token/i.test(message)) {
83
+ return `${message} \u2014 ${REJECTED_CREDENTIAL_HINT}`;
84
+ }
85
+ return message;
86
+ }
87
+ function asRecord(value) {
88
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
89
+ }
90
+ function parseSseJson(body) {
91
+ const blocks = body.split(/\n\n+/);
92
+ let last;
93
+ for (const block of blocks) {
94
+ const data = block.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice(5).trim()).filter((line) => line && line !== "[DONE]").join("\n");
95
+ if (!data) continue;
96
+ try {
97
+ last = JSON.parse(data);
98
+ } catch {
99
+ }
100
+ }
101
+ if (last !== void 0) return last;
102
+ try {
103
+ return JSON.parse(body);
104
+ } catch {
105
+ throw new Error(`AbleTime MCP returned a non-JSON response: ${body.slice(0, 200)}`);
106
+ }
107
+ }
108
+ function unwrapToolResult(result) {
109
+ const record = asRecord(result);
110
+ if (!record) return result;
111
+ const content = record.content;
112
+ if (Array.isArray(content)) {
113
+ const texts = content.map((part) => {
114
+ const item = asRecord(part);
115
+ if (!item) return "";
116
+ return typeof item.text === "string" ? item.text : "";
117
+ }).filter(Boolean);
118
+ if (texts.length === 1) {
119
+ const text = texts[0];
120
+ try {
121
+ return JSON.parse(text);
122
+ } catch {
123
+ return text;
124
+ }
125
+ }
126
+ if (texts.length > 1) return texts.join("\n");
127
+ }
128
+ if (record.structuredContent != null) return record.structuredContent;
129
+ if (record.isError === true) {
130
+ const message = typeof record.message === "string" ? record.message : textsFromUnknown(result) || "AbleTime tool failed";
131
+ throw new Error(message);
132
+ }
133
+ return result;
134
+ }
135
+ function textsFromUnknown(value) {
136
+ const record = asRecord(value);
137
+ if (!record) return "";
138
+ if (typeof record.message === "string") return record.message;
139
+ if (typeof record.error === "string") return record.error;
140
+ return "";
141
+ }
142
+ async function abletimeMcpRequest(method, params, opts) {
143
+ const rawToken = opts?.token ?? await import("./abletime-oauth-7TD5Z2QV.js").then((m) => m.ensureAbleTimeAccessToken());
144
+ if (!rawToken?.trim()) {
145
+ throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
146
+ }
147
+ const token = assertAbleTimeMcpCredential(rawToken);
148
+ const url = abletimeMcpUrl(
149
+ opts?.host ?? (opts?.token ? DEFAULT_ABLETIME_HOST : getAbleTimeHost()),
150
+ { pm: opts?.pm }
151
+ );
152
+ const res = await httpFetch(url, {
153
+ method: "POST",
154
+ headers: {
155
+ "Content-Type": "application/json",
156
+ Accept: "application/json, text/event-stream",
157
+ Authorization: `Bearer ${token}`,
158
+ "MCP-Protocol-Version": MCP_PROTOCOL_VERSION
159
+ },
160
+ body: JSON.stringify({
161
+ jsonrpc: "2.0",
162
+ id: 1,
163
+ method,
164
+ ...params === void 0 ? {} : { params }
165
+ })
166
+ });
167
+ const body = await res.text().catch(() => "");
168
+ if (!res.ok) {
169
+ throw new Error(
170
+ rewriteAbleTimeError(
171
+ `AbleTime MCP error ${res.status}${body ? `: ${body.slice(0, 240)}` : ""}`
172
+ )
173
+ );
174
+ }
175
+ const contentType = res.headers.get("content-type") ?? "";
176
+ const parsed = contentType.includes("text/event-stream") ? parseSseJson(body) : (() => {
177
+ try {
178
+ return JSON.parse(body);
179
+ } catch {
180
+ return parseSseJson(body);
181
+ }
182
+ })();
183
+ const rpc = asRecord(parsed);
184
+ if (rpc?.error) {
185
+ const detail = typeof rpc.error.message === "string" && rpc.error.message.trim() ? rpc.error.message : `AbleTime MCP error ${rpc.error.code ?? ""}`.trim();
186
+ throw new Error(rewriteAbleTimeError(detail));
187
+ }
188
+ if (rpc && "result" in rpc) return rpc.result;
189
+ return parsed;
190
+ }
191
+ async function initializeIfNeeded(opts) {
192
+ try {
193
+ await abletimeMcpRequest(
194
+ "initialize",
195
+ {
196
+ protocolVersion: MCP_PROTOCOL_VERSION,
197
+ capabilities: {},
198
+ clientInfo: { name: "sideboard", version: "1.0.0" }
199
+ },
200
+ opts
201
+ );
202
+ } catch (err) {
203
+ const message = err instanceof Error ? err.message : String(err);
204
+ if (/already initialized|not (required|supported)|method not found|-32601/i.test(message)) {
205
+ return;
206
+ }
207
+ throw err;
208
+ }
209
+ }
210
+ async function callAbleTimeTool(name, args = {}, opts) {
211
+ if (!opts?.token && !isAbleTimeConnected()) {
212
+ throw new Error("AbleTime is not connected \u2014 paste a personal access token in Account settings");
213
+ }
214
+ const rawToken = opts?.token ?? await import("./abletime-oauth-7TD5Z2QV.js").then((m) => m.ensureAbleTimeAccessToken());
215
+ if (rawToken && ableTimeCredentialKind(rawToken) === "org") {
216
+ const { callAbleTimeRestTool } = await import("./abletime-rest-QPJTDLKX.js");
217
+ return callAbleTimeRestTool(name, args, { ...opts, token: rawToken });
218
+ }
219
+ const requestOpts = { ...opts, pm: opts?.pm ?? abletimeToolUsesPm(name) };
220
+ const call = () => abletimeMcpRequest("tools/call", { name, arguments: args }, requestOpts).then((result) => {
221
+ return unwrapToolResult(result);
222
+ });
223
+ try {
224
+ return await call();
225
+ } catch (err) {
226
+ const message = err instanceof Error ? err.message : String(err);
227
+ if (/initialize|session|not initialized|-32000/i.test(message)) {
228
+ await initializeIfNeeded(requestOpts);
229
+ return await call();
230
+ }
231
+ throw err instanceof Error ? new Error(rewriteAbleTimeError(err.message)) : err;
232
+ }
233
+ }
234
+
235
+ export {
236
+ DEFAULT_ABLETIME_HOST,
237
+ normalizeAbleTimeHost,
238
+ normalizeAbleTimeCredential,
239
+ ableTimeCredentialKind,
240
+ assertAbleTimeCredential,
241
+ rewriteAbleTimeError,
242
+ callAbleTimeTool
243
+ };
@@ -328,6 +328,9 @@ function normalizeVault(raw) {
328
328
  if (typeof raw.abletimeAccessToken === "string" && raw.abletimeAccessToken.trim()) {
329
329
  out.abletimeAccessToken = raw.abletimeAccessToken.trim();
330
330
  }
331
+ if (typeof raw.abletimeRefreshToken === "string" && raw.abletimeRefreshToken.trim()) {
332
+ out.abletimeRefreshToken = raw.abletimeRefreshToken.trim();
333
+ }
331
334
  if (typeof raw.vercelToken === "string" && raw.vercelToken.trim()) {
332
335
  out.vercelToken = raw.vercelToken.trim();
333
336
  }
@@ -409,6 +412,7 @@ function emptyPublicIntegrations() {
409
412
  hasSlackAppToken: false,
410
413
  hasGithubPat: false,
411
414
  hasAbleTimeToken: false,
415
+ hasAbleTimeOAuth: false,
412
416
  hasVercelToken: false,
413
417
  hasSupabaseToken: false,
414
418
  hasPosthogToken: false,
@@ -433,6 +437,7 @@ function toPublicAppSettings(settings) {
433
437
  const slackAppToken = integrations.slackAppToken;
434
438
  const githubPat = integrations.githubPat;
435
439
  const abletimeAccessToken = integrations.abletimeAccessToken;
440
+ const abletimeRefreshToken = integrations.abletimeRefreshToken;
436
441
  const vercelToken = integrations.vercelToken;
437
442
  const supabaseAccessToken = integrations.supabaseAccessToken;
438
443
  const posthogPersonalApiKey = integrations.posthogPersonalApiKey;
@@ -445,6 +450,7 @@ function toPublicAppSettings(settings) {
445
450
  delete integrations.slackAppToken;
446
451
  delete integrations.githubPat;
447
452
  delete integrations.abletimeAccessToken;
453
+ delete integrations.abletimeRefreshToken;
448
454
  delete integrations.vercelToken;
449
455
  delete integrations.supabaseAccessToken;
450
456
  delete integrations.posthogPersonalApiKey;
@@ -459,7 +465,8 @@ function toPublicAppSettings(settings) {
459
465
  hasSlackClientSecret: Boolean(slackClientSecret?.trim()),
460
466
  hasSlackAppToken: Boolean(slackAppToken?.trim()),
461
467
  hasGithubPat: Boolean(githubPat?.trim()),
462
- hasAbleTimeToken: Boolean(abletimeAccessToken?.trim()),
468
+ hasAbleTimeToken: Boolean(abletimeAccessToken?.trim() || abletimeRefreshToken?.trim()),
469
+ hasAbleTimeOAuth: Boolean(abletimeRefreshToken?.trim()),
463
470
  hasVercelToken: Boolean(vercelToken?.trim()),
464
471
  hasSupabaseToken: Boolean(supabaseAccessToken?.trim()),
465
472
  hasPosthogToken: Boolean(posthogPersonalApiKey?.trim()),
@@ -605,6 +612,16 @@ function normalizeIntegrations(raw) {
605
612
  const token = source.abletimeAccessToken.trim();
606
613
  if (token) out.abletimeAccessToken = token;
607
614
  }
615
+ if (typeof source.abletimeRefreshToken === "string") {
616
+ const token = source.abletimeRefreshToken.trim();
617
+ if (token) out.abletimeRefreshToken = token;
618
+ }
619
+ if (typeof source.abletimeTokenExpiresAt === "number" && Number.isFinite(source.abletimeTokenExpiresAt)) {
620
+ out.abletimeTokenExpiresAt = source.abletimeTokenExpiresAt;
621
+ } else if (typeof source.abletimeTokenExpiresAt === "string") {
622
+ const n = Number(source.abletimeTokenExpiresAt);
623
+ if (Number.isFinite(n)) out.abletimeTokenExpiresAt = n;
624
+ }
608
625
  if (typeof source.abletimeHost === "string") {
609
626
  const host = source.abletimeHost.trim();
610
627
  if (host) out.abletimeHost = host;
@@ -893,7 +910,7 @@ function readSettingsFile() {
893
910
  }
894
911
  function diskHoldsSecrets(disk) {
895
912
  return Boolean(
896
- disk.integrations.linearApiKey || disk.integrations.linearAccessToken || disk.integrations.linearRefreshToken || disk.integrations.linearClientSecret || disk.integrations.slackClientSecret || disk.integrations.slackAppToken || disk.integrations.githubPat || disk.integrations.abletimeAccessToken || disk.integrations.vercelToken || disk.integrations.supabaseAccessToken || disk.integrations.posthogPersonalApiKey || disk.integrations.sentryAuthToken || Object.keys(disk.environment).length > 0
913
+ disk.integrations.linearApiKey || disk.integrations.linearAccessToken || disk.integrations.linearRefreshToken || disk.integrations.linearClientSecret || disk.integrations.slackClientSecret || disk.integrations.slackAppToken || disk.integrations.githubPat || disk.integrations.abletimeAccessToken || disk.integrations.abletimeRefreshToken || disk.integrations.vercelToken || disk.integrations.supabaseAccessToken || disk.integrations.posthogPersonalApiKey || disk.integrations.sentryAuthToken || Object.keys(disk.environment).length > 0
897
914
  );
898
915
  }
899
916
  function mergeVault(disk) {
@@ -924,6 +941,9 @@ function mergeVault(disk) {
924
941
  if (vault.abletimeAccessToken && !integrations.abletimeAccessToken) {
925
942
  integrations.abletimeAccessToken = vault.abletimeAccessToken;
926
943
  }
944
+ if (vault.abletimeRefreshToken && !integrations.abletimeRefreshToken) {
945
+ integrations.abletimeRefreshToken = vault.abletimeRefreshToken;
946
+ }
927
947
  if (vault.vercelToken && !integrations.vercelToken) {
928
948
  integrations.vercelToken = vault.vercelToken;
929
949
  }
@@ -948,6 +968,7 @@ function persistSplit(settings) {
948
968
  const slackAppToken = integrations.slackAppToken;
949
969
  const githubPat = integrations.githubPat;
950
970
  const abletimeAccessToken = integrations.abletimeAccessToken;
971
+ const abletimeRefreshToken = integrations.abletimeRefreshToken;
951
972
  const vercelToken = integrations.vercelToken;
952
973
  const supabaseAccessToken = integrations.supabaseAccessToken;
953
974
  const posthogPersonalApiKey = integrations.posthogPersonalApiKey;
@@ -960,6 +981,7 @@ function persistSplit(settings) {
960
981
  delete integrations.slackAppToken;
961
982
  delete integrations.githubPat;
962
983
  delete integrations.abletimeAccessToken;
984
+ delete integrations.abletimeRefreshToken;
963
985
  delete integrations.vercelToken;
964
986
  delete integrations.supabaseAccessToken;
965
987
  delete integrations.posthogPersonalApiKey;
@@ -978,6 +1000,7 @@ function persistSplit(settings) {
978
1000
  slackAppToken,
979
1001
  githubPat,
980
1002
  abletimeAccessToken,
1003
+ abletimeRefreshToken,
981
1004
  vercelToken,
982
1005
  supabaseAccessToken,
983
1006
  posthogPersonalApiKey,
@@ -1164,6 +1187,8 @@ function updateIntegrationsSettings(patch) {
1164
1187
  if ("abletimeAccessToken" in patch) {
1165
1188
  if (patch.abletimeAccessToken == null || patch.abletimeAccessToken.trim() === "") {
1166
1189
  delete integrations.abletimeAccessToken;
1190
+ delete integrations.abletimeRefreshToken;
1191
+ delete integrations.abletimeTokenExpiresAt;
1167
1192
  delete integrations.abletimeViewerName;
1168
1193
  } else {
1169
1194
  integrations.abletimeAccessToken = patch.abletimeAccessToken.trim();
@@ -1516,7 +1541,9 @@ function disconnectLinearConnection() {
1516
1541
  return saveAppSettings({ ...current, integrations });
1517
1542
  }
1518
1543
  function isAbleTimeConnected(settings = loadAppSettings()) {
1519
- return Boolean(settings.integrations.abletimeAccessToken?.trim());
1544
+ return Boolean(
1545
+ settings.integrations.abletimeAccessToken?.trim() || settings.integrations.abletimeRefreshToken?.trim()
1546
+ );
1520
1547
  }
1521
1548
  function getAbleTimeAccessToken(settings = loadAppSettings()) {
1522
1549
  const token = settings.integrations.abletimeAccessToken?.trim();
@@ -1529,6 +1556,12 @@ function saveAbleTimeConnection(input) {
1529
1556
  const current = loadAppSettings();
1530
1557
  const integrations = { ...current.integrations };
1531
1558
  integrations.abletimeAccessToken = input.accessToken.trim();
1559
+ if (input.refreshToken?.trim()) {
1560
+ integrations.abletimeRefreshToken = input.refreshToken.trim();
1561
+ }
1562
+ if (typeof input.expiresIn === "number" && Number.isFinite(input.expiresIn)) {
1563
+ integrations.abletimeTokenExpiresAt = Date.now() + Math.max(0, input.expiresIn) * 1e3;
1564
+ }
1532
1565
  if (input.host?.trim()) {
1533
1566
  integrations.abletimeHost = input.host.trim();
1534
1567
  }
@@ -1541,6 +1574,8 @@ function disconnectAbleTimeConnection() {
1541
1574
  const current = loadAppSettings();
1542
1575
  const integrations = { ...current.integrations };
1543
1576
  delete integrations.abletimeAccessToken;
1577
+ delete integrations.abletimeRefreshToken;
1578
+ delete integrations.abletimeTokenExpiresAt;
1544
1579
  delete integrations.abletimeViewerName;
1545
1580
  return saveAppSettings({ ...current, integrations });
1546
1581
  }
@@ -22,7 +22,7 @@ import {
22
22
  import {
23
23
  getGithubGitAuthMode,
24
24
  getGithubPat
25
- } from "./chunk-ISV5IFH3.js";
25
+ } from "./chunk-X743YN5Y.js";
26
26
  import {
27
27
  worktreesRoot
28
28
  } from "./chunk-EQNRWDLN.js";
@@ -5,7 +5,7 @@ import {
5
5
  resolveRepoRoot,
6
6
  takenSlugsFromThread,
7
7
  teamSlugFromName
8
- } from "./chunk-STPZQR5B.js";
8
+ } from "./chunk-CMGRV36E.js";
9
9
  import {
10
10
  ATTACHMENTS_DIR,
11
11
  attachmentsGitignoreBody
@@ -22,7 +22,7 @@ import {
22
22
  resolveThreadDefaults,
23
23
  resolveViewerProfile,
24
24
  resolveViewerProfileForRepo
25
- } from "./chunk-CXFW5LIH.js";
25
+ } from "./chunk-QFBBUFD4.js";
26
26
  import {
27
27
  createEmptyThread,
28
28
  listThreads,