clairo 1.2.0 → 1.2.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 (3) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +295 -217
  3. package/package.json +2 -1
package/README.md CHANGED
@@ -8,7 +8,7 @@ dashboard tui for github PRs, jira tickets, and daily logs.
8
8
  - claude code integration (requires claude code to be set up) for generating standup notes
9
9
  - link jira tickets and change ticket status from the terminal
10
10
  - auto jira ticket detection based on branch name
11
- - daily logs that update automatically with tui actions that can be used for generateStandupNotes
11
+ - daily logs that update automatically with tui actions that can be used to generate standup notes
12
12
 
13
13
  ## requirements
14
14
 
package/dist/cli.js CHANGED
@@ -5,12 +5,12 @@ import meow from "meow";
5
5
 
6
6
  // src/app.tsx
7
7
  import { useCallback as useCallback9, useMemo as useMemo2, useState as useState16 } from "react";
8
- import { Box as Box16, useApp, useInput as useInput13 } from "ink";
8
+ import { Box as Box17, useApp, useInput as useInput13 } from "ink";
9
9
 
10
10
  // src/components/github/GitHubView.tsx
11
11
  import { useCallback as useCallback8, useEffect as useEffect8, useRef as useRef5, useState as useState11 } from "react";
12
12
  import { TitledBox as TitledBox3 } from "@mishieck/ink-titled-box";
13
- import { Box as Box5, Text as Text5, useInput as useInput4 } from "ink";
13
+ import { Box as Box6, Text as Text5, useInput as useInput4 } from "ink";
14
14
  import { ScrollView as ScrollView4 } from "ink-scroll-view";
15
15
 
16
16
  // src/hooks/github/useGitRepo.ts
@@ -174,6 +174,22 @@ function findRemoteWithBranch(branch) {
174
174
  import { exec, execFile } from "child_process";
175
175
  import { promisify } from "util";
176
176
  var execAsync = promisify(exec);
177
+ function timeAgo(dateStr) {
178
+ const seconds = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1e3);
179
+ const intervals = [
180
+ [86400 * 365, "year"],
181
+ [86400 * 30, "month"],
182
+ [86400 * 7, "week"],
183
+ [86400, "day"],
184
+ [3600, "hour"],
185
+ [60, "minute"]
186
+ ];
187
+ for (const [secs, label] of intervals) {
188
+ const count = Math.floor(seconds / secs);
189
+ if (count >= 1) return `${count} ${label}${count > 1 ? "s" : ""} ago`;
190
+ }
191
+ return "just now";
192
+ }
177
193
  function resolveCheckStatus(check) {
178
194
  const conclusion = check.conclusion ?? check.state;
179
195
  if (conclusion === "SUCCESS" || check.status === "COMPLETED") return "success";
@@ -201,6 +217,7 @@ function resolveMergeDisplay(pr) {
201
217
  if (!pr) return { text: "UNKNOWN", color: "yellow" };
202
218
  if (pr.state === "MERGED") return { text: "MERGED", color: "magenta" };
203
219
  if (pr.state === "CLOSED") return { text: "CLOSED", color: "red" };
220
+ if (pr.isDraft) return { text: "DRAFT", color: "yellow" };
204
221
  if (pr.mergeable === "MERGEABLE") return { text: "MERGEABLE", color: "green" };
205
222
  if (pr.mergeable === "CONFLICTING") return { text: "CONFLICTING", color: "red" };
206
223
  return { text: pr.mergeable ?? "UNKNOWN", color: "yellow" };
@@ -287,6 +304,11 @@ async function getPRDetails(prNumber, repo) {
287
304
  "updatedAt",
288
305
  "isDraft",
289
306
  "mergeable",
307
+ "baseRefName",
308
+ "headRefName",
309
+ "additions",
310
+ "deletions",
311
+ "labels",
290
312
  "reviewDecision",
291
313
  "commits",
292
314
  "assignees",
@@ -701,7 +723,7 @@ function generatePRContent() {
701
723
 
702
724
  Rules:
703
725
  - "title": a concise PR title in imperative mood, under 72 characters
704
- - "body": a markdown PR description summarizing what changed and why. Use bullet points for multiple changes.
726
+ - "body": a markdown PR description focusing on the motivation and what the PR achieves at a high level. Keep it concise \u2014 a short paragraph or two is ideal. Use bullet points only when there are genuinely distinct changes worth calling out separately. For larger PRs, organize with markdown sections (## headings) to break up the description.
705
727
  - Do not include any text outside the JSON object
706
728
  - Do not add any "Co-Authored-By" or attribution lines`;
707
729
  return runClaudePrompt(prompt);
@@ -1100,24 +1122,43 @@ ${oldStatus} \u2192 ${newStatus}
1100
1122
  // src/components/github/PRDetailsBox.tsx
1101
1123
  import open from "open";
1102
1124
  import { useRef as useRef2 } from "react";
1103
- import { Box as Box2, Text as Text2, useInput, useStdout } from "ink";
1125
+ import { Box as Box3, Text as Text2, useInput, useStdout } from "ink";
1104
1126
  import { ScrollView } from "ink-scroll-view";
1105
1127
 
1128
+ // src/components/ui/Divider.tsx
1129
+ import { Box } from "ink";
1130
+ import { jsx } from "react/jsx-runtime";
1131
+ function Divider({ color }) {
1132
+ return /* @__PURE__ */ jsx(
1133
+ Box,
1134
+ {
1135
+ flexGrow: 1,
1136
+ height: 0,
1137
+ borderStyle: "round",
1138
+ borderBottom: false,
1139
+ borderLeft: false,
1140
+ borderRight: false,
1141
+ borderColor: color,
1142
+ borderDimColor: !color
1143
+ }
1144
+ );
1145
+ }
1146
+
1106
1147
  // src/components/ui/Markdown.tsx
1107
1148
  import Table from "cli-table3";
1108
1149
  import { marked } from "marked";
1109
- import { Box, Text } from "ink";
1150
+ import { Box as Box2, Text } from "ink";
1110
1151
  import Link from "ink-link";
1111
- import { jsx, jsxs } from "react/jsx-runtime";
1152
+ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
1112
1153
  function Markdown({ children }) {
1113
1154
  const tokens = marked.lexer(children);
1114
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: tokens.map((token, idx) => /* @__PURE__ */ jsx(TokenRenderer, { token }, idx)) });
1155
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: tokens.map((token, idx) => /* @__PURE__ */ jsx2(TokenRenderer, { token }, idx)) });
1115
1156
  }
1116
1157
  function TokenRenderer({ token }) {
1117
1158
  var _a, _b;
1118
1159
  switch (token.type) {
1119
1160
  case "heading":
1120
- return /* @__PURE__ */ jsx(Box, { marginTop: token.depth === 1 ? 0 : 1, children: /* @__PURE__ */ jsx(Text, { bold: true, underline: token.depth === 1, children: renderInline(token.tokens) }) });
1161
+ return /* @__PURE__ */ jsx2(Box2, { marginTop: token.depth === 1 ? 0 : 1, children: /* @__PURE__ */ jsx2(Text, { bold: true, underline: token.depth === 1, children: renderInline(token.tokens) }) });
1121
1162
  case "paragraph": {
1122
1163
  const hasLinks = (_a = token.tokens) == null ? void 0 : _a.some(
1123
1164
  (t) => {
@@ -1126,31 +1167,31 @@ function TokenRenderer({ token }) {
1126
1167
  }
1127
1168
  );
1128
1169
  if (hasLinks) {
1129
- return /* @__PURE__ */ jsx(Box, { flexDirection: "row", flexWrap: "wrap", children: renderInline(token.tokens) });
1170
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "row", flexWrap: "wrap", children: renderInline(token.tokens) });
1130
1171
  }
1131
- return /* @__PURE__ */ jsx(Text, { children: renderInline(token.tokens) });
1172
+ return /* @__PURE__ */ jsx2(Text, { children: renderInline(token.tokens) });
1132
1173
  }
1133
1174
  case "code":
1134
- return /* @__PURE__ */ jsx(Box, { marginY: 1, paddingX: 1, borderStyle: "single", borderColor: "gray", children: /* @__PURE__ */ jsx(Text, { dimColor: true, children: token.text }) });
1175
+ return /* @__PURE__ */ jsx2(Box2, { marginY: 1, paddingX: 1, borderStyle: "single", borderColor: "gray", children: /* @__PURE__ */ jsx2(Text, { dimColor: true, children: token.text }) });
1135
1176
  case "blockquote":
1136
- return /* @__PURE__ */ jsxs(Box, { marginLeft: 2, children: [
1137
- /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u2502 " }),
1138
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: (_b = token.tokens) == null ? void 0 : _b.map((t, idx) => /* @__PURE__ */ jsx(TokenRenderer, { token: t }, idx)) })
1177
+ return /* @__PURE__ */ jsxs(Box2, { marginLeft: 2, children: [
1178
+ /* @__PURE__ */ jsx2(Text, { color: "gray", children: "\u2502 " }),
1179
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: (_b = token.tokens) == null ? void 0 : _b.map((t, idx) => /* @__PURE__ */ jsx2(TokenRenderer, { token: t }, idx)) })
1139
1180
  ] });
1140
1181
  case "list":
1141
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginY: 1, children: token.items.map((item, idx) => /* @__PURE__ */ jsxs(Box, { children: [
1142
- /* @__PURE__ */ jsx(Text, { children: token.ordered ? `${idx + 1}. ` : "\u2022 " }),
1143
- /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: item.tokens.map((t, i) => /* @__PURE__ */ jsx(TokenRenderer, { token: t }, i)) })
1182
+ return /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", marginY: 1, children: token.items.map((item, idx) => /* @__PURE__ */ jsxs(Box2, { children: [
1183
+ /* @__PURE__ */ jsx2(Text, { children: token.ordered ? `${idx + 1}. ` : "\u2022 " }),
1184
+ /* @__PURE__ */ jsx2(Box2, { flexDirection: "column", children: item.tokens.map((t, i) => /* @__PURE__ */ jsx2(TokenRenderer, { token: t }, i)) })
1144
1185
  ] }, idx)) });
1145
1186
  case "table":
1146
- return /* @__PURE__ */ jsx(TableRenderer, { token });
1187
+ return /* @__PURE__ */ jsx2(TableRenderer, { token });
1147
1188
  case "hr":
1148
- return /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2500".repeat(40) });
1189
+ return /* @__PURE__ */ jsx2(Text, { dimColor: true, children: "\u2500".repeat(40) });
1149
1190
  case "space":
1150
1191
  return null;
1151
1192
  default:
1152
1193
  if ("text" in token && typeof token.text === "string") {
1153
- return /* @__PURE__ */ jsx(Text, { children: token.text });
1194
+ return /* @__PURE__ */ jsx2(Text, { children: token.text });
1154
1195
  }
1155
1196
  return null;
1156
1197
  }
@@ -1163,18 +1204,18 @@ function TableRenderer({ token }) {
1163
1204
  for (const row of token.rows) {
1164
1205
  table.push(row.map((cell) => renderInlineToString(cell.tokens)));
1165
1206
  }
1166
- return /* @__PURE__ */ jsx(Text, { children: table.toString() });
1207
+ return /* @__PURE__ */ jsx2(Text, { children: table.toString() });
1167
1208
  }
1168
1209
  function renderInline(tokens) {
1169
1210
  if (!tokens) return null;
1170
1211
  return tokens.map((token, idx) => {
1171
1212
  switch (token.type) {
1172
1213
  case "text":
1173
- return /* @__PURE__ */ jsx(Text, { children: token.text }, idx);
1214
+ return /* @__PURE__ */ jsx2(Text, { children: token.text }, idx);
1174
1215
  case "strong":
1175
- return /* @__PURE__ */ jsx(Text, { bold: true, children: renderInline(token.tokens) }, idx);
1216
+ return /* @__PURE__ */ jsx2(Text, { bold: true, children: renderInline(token.tokens) }, idx);
1176
1217
  case "em":
1177
- return /* @__PURE__ */ jsx(Text, { italic: true, children: renderInline(token.tokens) }, idx);
1218
+ return /* @__PURE__ */ jsx2(Text, { italic: true, children: renderInline(token.tokens) }, idx);
1178
1219
  case "codespan":
1179
1220
  return /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
1180
1221
  "`",
@@ -1182,7 +1223,7 @@ function renderInline(tokens) {
1182
1223
  "`"
1183
1224
  ] }, idx);
1184
1225
  case "link":
1185
- return /* @__PURE__ */ jsx(Link, { url: token.href, children: /* @__PURE__ */ jsx(Text, { color: "blue", children: renderInlineToString(token.tokens) }) }, idx);
1226
+ return /* @__PURE__ */ jsx2(Link, { url: token.href, children: /* @__PURE__ */ jsx2(Text, { color: "blue", children: renderInlineToString(token.tokens) }) }, idx);
1186
1227
  case "image":
1187
1228
  return /* @__PURE__ */ jsxs(Text, { color: "blue", children: [
1188
1229
  "[Image: ",
@@ -1190,12 +1231,12 @@ function renderInline(tokens) {
1190
1231
  "]"
1191
1232
  ] }, idx);
1192
1233
  case "br":
1193
- return /* @__PURE__ */ jsx(Text, { children: "\n" }, idx);
1234
+ return /* @__PURE__ */ jsx2(Text, { children: "\n" }, idx);
1194
1235
  case "del":
1195
- return /* @__PURE__ */ jsx(Text, { strikethrough: true, children: renderInline(token.tokens) }, idx);
1236
+ return /* @__PURE__ */ jsx2(Text, { strikethrough: true, children: renderInline(token.tokens) }, idx);
1196
1237
  default:
1197
1238
  if ("text" in token && typeof token.text === "string") {
1198
- return /* @__PURE__ */ jsx(Text, { children: token.text }, idx);
1239
+ return /* @__PURE__ */ jsx2(Text, { children: token.text }, idx);
1199
1240
  }
1200
1241
  return null;
1201
1242
  }
@@ -1215,9 +1256,9 @@ function renderInlineToString(tokens) {
1215
1256
  }
1216
1257
 
1217
1258
  // src/components/github/PRDetailsBox.tsx
1218
- import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
1259
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
1219
1260
  function PRDetailsBox({ pr, loading, error, isActive }) {
1220
- var _a, _b, _c, _d, _e, _f, _g;
1261
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1221
1262
  const scrollRef = useRef2(null);
1222
1263
  const title = "[3] PR Details";
1223
1264
  const borderColor = isActive ? "yellow" : void 0;
@@ -1243,13 +1284,13 @@ function PRDetailsBox({ pr, loading, error, isActive }) {
1243
1284
  const { stdout } = useStdout();
1244
1285
  const terminalWidth = (stdout == null ? void 0 : stdout.columns) ?? 80;
1245
1286
  const columnWidth = Math.floor(terminalWidth / 2);
1246
- const titlePart = `\u256D\u2500 ${displayTitle} `;
1287
+ const titlePart = `\u256D ${displayTitle} `;
1247
1288
  const dashCount = Math.max(0, columnWidth - titlePart.length - 1);
1248
1289
  const topBorder = `${titlePart}${"\u2500".repeat(dashCount)}\u256E`;
1249
- return /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", flexGrow: 1, children: [
1250
- /* @__PURE__ */ jsx2(Text2, { color: borderColor, children: topBorder }),
1251
- /* @__PURE__ */ jsx2(
1252
- Box2,
1290
+ return /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", flexGrow: 1, children: [
1291
+ /* @__PURE__ */ jsx3(Text2, { color: borderColor, children: topBorder }),
1292
+ /* @__PURE__ */ jsx3(
1293
+ Box3,
1253
1294
  {
1254
1295
  flexDirection: "column",
1255
1296
  flexGrow: 1,
@@ -1258,33 +1299,57 @@ function PRDetailsBox({ pr, loading, error, isActive }) {
1258
1299
  borderStyle: "round",
1259
1300
  borderTop: false,
1260
1301
  borderColor,
1261
- children: /* @__PURE__ */ jsx2(ScrollView, { ref: scrollRef, children: /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", paddingX: 1, children: [
1262
- loading && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Loading details..." }),
1263
- error && /* @__PURE__ */ jsx2(Text2, { color: "red", children: error }),
1264
- !loading && !error && !pr && /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Select a PR to view details" }),
1302
+ children: /* @__PURE__ */ jsx3(ScrollView, { ref: scrollRef, children: /* @__PURE__ */ jsxs2(Box3, { flexDirection: "column", paddingX: 1, children: [
1303
+ loading && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "Loading details..." }),
1304
+ error && /* @__PURE__ */ jsx3(Text2, { color: "red", children: error }),
1305
+ !loading && !error && !pr && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "Select a PR to view details" }),
1265
1306
  !loading && !error && pr && /* @__PURE__ */ jsxs2(Fragment, { children: [
1266
- /* @__PURE__ */ jsx2(Text2, { bold: true, children: pr.title }),
1267
- /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
1268
- "by ",
1269
- ((_a = pr.author) == null ? void 0 : _a.login) ?? "unknown",
1270
- " | ",
1271
- ((_b = pr.commits) == null ? void 0 : _b.length) ?? 0,
1272
- " commits"
1307
+ /* @__PURE__ */ jsxs2(Box3, { children: [
1308
+ /* @__PURE__ */ jsxs2(Text2, { bold: true, children: [
1309
+ pr.title,
1310
+ " "
1311
+ ] }),
1312
+ /* @__PURE__ */ jsx3(Text2, { color: mergeDisplay.color, children: "\uE0B6" }),
1313
+ /* @__PURE__ */ jsx3(Text2, { color: "black", backgroundColor: mergeDisplay.color, bold: true, children: `${mergeDisplay.text}` }),
1314
+ /* @__PURE__ */ jsx3(Text2, { color: mergeDisplay.color, children: "\uE0B4" })
1273
1315
  ] }),
1274
- /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, children: [
1275
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Review: " }),
1276
- /* @__PURE__ */ jsx2(Text2, { color: reviewDisplay.color, children: reviewDisplay.text }),
1277
- /* @__PURE__ */ jsx2(Text2, { children: " | " }),
1278
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Status: " }),
1279
- /* @__PURE__ */ jsx2(Text2, { color: mergeDisplay.color, children: mergeDisplay.text })
1316
+ /* @__PURE__ */ jsxs2(Box3, { children: [
1317
+ /* @__PURE__ */ jsxs2(Text2, { dimColor: true, children: [
1318
+ pr.baseRefName,
1319
+ " \u2190 ",
1320
+ pr.headRefName,
1321
+ " | by ",
1322
+ ((_a = pr.author) == null ? void 0 : _a.login) ?? "unknown",
1323
+ " | ",
1324
+ ((_b = pr.commits) == null ? void 0 : _b.length) ?? 0,
1325
+ " ",
1326
+ "commits",
1327
+ pr.createdAt && ` | opened ${timeAgo(pr.createdAt)}`,
1328
+ " |",
1329
+ " "
1330
+ ] }),
1331
+ /* @__PURE__ */ jsxs2(Text2, { color: "green", children: [
1332
+ "+",
1333
+ pr.additions
1334
+ ] }),
1335
+ /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: " " }),
1336
+ /* @__PURE__ */ jsxs2(Text2, { color: "red", children: [
1337
+ "-",
1338
+ pr.deletions
1339
+ ] })
1280
1340
  ] }),
1281
- (((_c = pr.assignees) == null ? void 0 : _c.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, children: [
1282
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Assignees: " }),
1283
- /* @__PURE__ */ jsx2(Text2, { children: pr.assignees.map((a) => a.login).join(", ") })
1341
+ (((_c = pr.labels) == null ? void 0 : _c.length) ?? 0) > 0 && /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: pr.labels.map((l) => l.name).join(", ") }),
1342
+ /* @__PURE__ */ jsx3(Box3, { marginTop: 1, children: /* @__PURE__ */ jsx3(Divider, {}) }),
1343
+ (((_d = pr.assignees) == null ? void 0 : _d.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box3, { marginTop: 1, children: [
1344
+ /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "Assignees: " }),
1345
+ /* @__PURE__ */ jsx3(Text2, { children: pr.assignees.map((a) => a.login).join(", ") })
1284
1346
  ] }),
1285
- (((_d = pr.reviews) == null ? void 0 : _d.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { flexDirection: "column", children: [
1286
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Reviews:" }),
1287
- pr.reviews.map((review, idx) => {
1347
+ ((((_e = pr.reviews) == null ? void 0 : _e.length) ?? 0) > 0 || (((_f = pr.reviewRequests) == null ? void 0 : _f.length) ?? 0) > 0) && /* @__PURE__ */ jsxs2(Box3, { marginTop: 1, flexDirection: "column", children: [
1348
+ /* @__PURE__ */ jsxs2(Box3, { children: [
1349
+ /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "Reviews: " }),
1350
+ /* @__PURE__ */ jsx3(Text2, { color: reviewDisplay.color, children: reviewDisplay.text })
1351
+ ] }),
1352
+ (_g = pr.reviews) == null ? void 0 : _g.map((review, idx) => {
1288
1353
  const color = review.state === "APPROVED" ? "green" : review.state === "CHANGES_REQUESTED" ? "red" : review.state === "COMMENTED" ? "blue" : "yellow";
1289
1354
  const icon = review.state === "APPROVED" ? "\u2713" : review.state === "CHANGES_REQUESTED" ? "\u2717" : review.state === "COMMENTED" ? "\u{1F4AC}" : "\u25CB";
1290
1355
  return /* @__PURE__ */ jsxs2(Text2, { color, children: [
@@ -1293,16 +1358,20 @@ function PRDetailsBox({ pr, loading, error, isActive }) {
1293
1358
  " ",
1294
1359
  review.author.login
1295
1360
  ] }, idx);
1296
- })
1297
- ] }),
1298
- (((_e = pr.reviewRequests) == null ? void 0 : _e.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { children: [
1299
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Pending: " }),
1300
- /* @__PURE__ */ jsx2(Text2, { color: "yellow", children: pr.reviewRequests.map((r) => r.login ?? r.name ?? r.slug ?? "Team").join(", ") })
1361
+ }),
1362
+ (_h = pr.reviewRequests) == null ? void 0 : _h.map((r, idx) => /* @__PURE__ */ jsxs2(Text2, { color: "yellow", children: [
1363
+ " ",
1364
+ "\u25CB ",
1365
+ r.login ?? r.name ?? r.slug ?? "Team",
1366
+ " ",
1367
+ /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "(pending)" })
1368
+ ] }, `pending-${idx}`))
1301
1369
  ] }),
1302
- (((_f = pr.statusCheckRollup) == null ? void 0 : _f.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
1303
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Checks:" }),
1370
+ (((_i = pr.statusCheckRollup) == null ? void 0 : _i.length) ?? 0) > 0 && /* @__PURE__ */ jsxs2(Box3, { marginTop: 1, flexDirection: "column", children: [
1371
+ /* @__PURE__ */ jsx3(Divider, {}),
1372
+ /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "Checks:" }),
1304
1373
  Array.from(
1305
- ((_g = pr.statusCheckRollup) == null ? void 0 : _g.reduce((acc, check) => {
1374
+ ((_j = pr.statusCheckRollup) == null ? void 0 : _j.reduce((acc, check) => {
1306
1375
  const key = check.name ?? check.context ?? "";
1307
1376
  const existing = acc.get(key);
1308
1377
  if (!existing || (check.startedAt ?? "") > (existing.startedAt ?? "")) {
@@ -1322,9 +1391,10 @@ function PRDetailsBox({ pr, loading, error, isActive }) {
1322
1391
  ] }, idx);
1323
1392
  })
1324
1393
  ] }),
1325
- pr.body && /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, flexDirection: "column", children: [
1326
- /* @__PURE__ */ jsx2(Text2, { dimColor: true, children: "Description:" }),
1327
- /* @__PURE__ */ jsx2(Markdown, { children: pr.body })
1394
+ pr.body && /* @__PURE__ */ jsxs2(Box3, { marginTop: 1, flexDirection: "column", children: [
1395
+ /* @__PURE__ */ jsx3(Divider, {}),
1396
+ /* @__PURE__ */ jsx3(Text2, { dimColor: true, children: "Description:" }),
1397
+ /* @__PURE__ */ jsx3(Markdown, { children: pr.body })
1328
1398
  ] })
1329
1399
  ] })
1330
1400
  ] }) })
@@ -1337,8 +1407,9 @@ function PRDetailsBox({ pr, loading, error, isActive }) {
1337
1407
  import open2 from "open";
1338
1408
  import { useState as useState10 } from "react";
1339
1409
  import { TitledBox } from "@mishieck/ink-titled-box";
1340
- import { Box as Box3, Text as Text3, useInput as useInput3 } from "ink";
1410
+ import { Box as Box4, Text as Text3, useInput as useInput3 } from "ink";
1341
1411
  import { ScrollView as ScrollView2 } from "ink-scroll-view";
1412
+ import Spinner from "ink-spinner";
1342
1413
 
1343
1414
  // src/hooks/jira/useJiraTickets.ts
1344
1415
  import { useCallback as useCallback4, useState as useState5 } from "react";
@@ -1765,7 +1836,7 @@ async function copyToClipboard(text) {
1765
1836
  }
1766
1837
 
1767
1838
  // src/components/github/PullRequestsBox.tsx
1768
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1839
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1769
1840
  function PullRequestsBox({
1770
1841
  prs,
1771
1842
  selectedPR,
@@ -1815,25 +1886,28 @@ function PullRequestsBox({
1815
1886
  const subtitle = branch ? ` (${branch})` : "";
1816
1887
  const copiedIndicator = copied ? " [Copied!]" : "";
1817
1888
  const borderColor = isActive ? "yellow" : void 0;
1818
- return /* @__PURE__ */ jsx3(
1889
+ return /* @__PURE__ */ jsx4(
1819
1890
  TitledBox,
1820
1891
  {
1821
1892
  borderStyle: "round",
1822
1893
  titles: [`${title}${subtitle}${copiedIndicator}`],
1823
1894
  borderColor,
1824
1895
  height: 5,
1825
- children: /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
1826
- loading && /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "Loading PRs..." }),
1827
- error && /* @__PURE__ */ jsx3(Text3, { color: "red", children: error }),
1828
- isGeneratingPR && /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: "Generating PR with Claude... (Esc to cancel)" }),
1896
+ children: /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
1897
+ loading && /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: "Loading PRs..." }),
1898
+ error && /* @__PURE__ */ jsx4(Text3, { color: "red", children: error }),
1899
+ isGeneratingPR && /* @__PURE__ */ jsxs3(Text3, { color: "yellow", children: [
1900
+ /* @__PURE__ */ jsx4(Spinner, { type: "dots" }),
1901
+ " Generating PR with Claude... (Esc to cancel)"
1902
+ ] }),
1829
1903
  !loading && !error && /* @__PURE__ */ jsxs3(ScrollView2, { ref: scrollRef, children: [
1830
- prs.length === 0 && /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "No PRs for this branch" }, "empty"),
1904
+ prs.length === 0 && /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: "No PRs for this branch" }, "empty"),
1831
1905
  prs.map((pr, idx) => {
1832
1906
  const isHighlighted = isActive && idx === highlightedIndex;
1833
1907
  const isSelected = pr.number === (selectedPR == null ? void 0 : selectedPR.number);
1834
1908
  const cursor = isHighlighted ? ">" : " ";
1835
1909
  const indicator = isSelected ? " *" : "";
1836
- return /* @__PURE__ */ jsxs3(Box3, { children: [
1910
+ return /* @__PURE__ */ jsxs3(Box4, { children: [
1837
1911
  /* @__PURE__ */ jsxs3(Text3, { color: isHighlighted ? "yellow" : void 0, children: [
1838
1912
  cursor,
1839
1913
  " "
@@ -1845,7 +1919,7 @@ function PullRequestsBox({
1845
1919
  pr.isDraft ? "[Draft] " : "",
1846
1920
  pr.title
1847
1921
  ] }),
1848
- /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: indicator })
1922
+ /* @__PURE__ */ jsx4(Text3, { dimColor: true, children: indicator })
1849
1923
  ] }, pr.number);
1850
1924
  }),
1851
1925
  /* @__PURE__ */ jsxs3(Text3, { color: "blue", children: [
@@ -1860,9 +1934,9 @@ function PullRequestsBox({
1860
1934
 
1861
1935
  // src/components/github/RemotesBox.tsx
1862
1936
  import { TitledBox as TitledBox2 } from "@mishieck/ink-titled-box";
1863
- import { Box as Box4, Text as Text4 } from "ink";
1937
+ import { Box as Box5, Text as Text4 } from "ink";
1864
1938
  import { ScrollView as ScrollView3 } from "ink-scroll-view";
1865
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1939
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1866
1940
  function RemotesBox({ remotes, selectedRemote, onSelect, loading, error, isActive }) {
1867
1941
  const selectedIndex = remotes.findIndex((r) => r.name === selectedRemote);
1868
1942
  const { highlightedIndex, scrollRef } = useListNavigation({
@@ -1873,16 +1947,16 @@ function RemotesBox({ remotes, selectedRemote, onSelect, loading, error, isActiv
1873
1947
  });
1874
1948
  const title = "[1] Remotes";
1875
1949
  const borderColor = isActive ? "yellow" : void 0;
1876
- return /* @__PURE__ */ jsx4(TitledBox2, { borderStyle: "round", titles: [title], borderColor, height: 5, children: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
1877
- loading && /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "Loading..." }),
1878
- error && /* @__PURE__ */ jsx4(Text4, { color: "red", children: error }),
1879
- !loading && !error && remotes.length === 0 && /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "No remotes configured" }),
1880
- !loading && !error && remotes.length > 0 && /* @__PURE__ */ jsx4(ScrollView3, { ref: scrollRef, children: remotes.map((remote, idx) => {
1950
+ return /* @__PURE__ */ jsx5(TitledBox2, { borderStyle: "round", titles: [title], borderColor, height: 5, children: /* @__PURE__ */ jsxs4(Box5, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
1951
+ loading && /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "Loading..." }),
1952
+ error && /* @__PURE__ */ jsx5(Text4, { color: "red", children: error }),
1953
+ !loading && !error && remotes.length === 0 && /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: "No remotes configured" }),
1954
+ !loading && !error && remotes.length > 0 && /* @__PURE__ */ jsx5(ScrollView3, { ref: scrollRef, children: remotes.map((remote, idx) => {
1881
1955
  const isHighlighted = isActive && idx === highlightedIndex;
1882
1956
  const isSelected = remote.name === selectedRemote;
1883
1957
  const cursor = isHighlighted ? ">" : " ";
1884
1958
  const indicator = isSelected ? " *" : "";
1885
- return /* @__PURE__ */ jsxs4(Box4, { children: [
1959
+ return /* @__PURE__ */ jsxs4(Box5, { children: [
1886
1960
  /* @__PURE__ */ jsxs4(Text4, { color: isHighlighted ? "yellow" : void 0, children: [
1887
1961
  cursor,
1888
1962
  " "
@@ -1893,14 +1967,14 @@ function RemotesBox({ remotes, selectedRemote, onSelect, loading, error, isActiv
1893
1967
  remote.url,
1894
1968
  ")"
1895
1969
  ] }),
1896
- /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: indicator })
1970
+ /* @__PURE__ */ jsx5(Text4, { dimColor: true, children: indicator })
1897
1971
  ] }, remote.name);
1898
1972
  }) })
1899
1973
  ] }) });
1900
1974
  }
1901
1975
 
1902
1976
  // src/components/github/GitHubView.tsx
1903
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1977
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1904
1978
  function GitHubView({ isActive, onFocusedBoxChange, onLogUpdated }) {
1905
1979
  const repo = useGitRepo();
1906
1980
  const pullRequests = usePullRequests();
@@ -2116,10 +2190,10 @@ ${body}`;
2116
2190
  { isActive }
2117
2191
  );
2118
2192
  if (repo.isRepo === false) {
2119
- return /* @__PURE__ */ jsx5(TitledBox3, { borderStyle: "round", titles: ["Error"], flexGrow: 1, children: /* @__PURE__ */ jsx5(Text5, { color: "red", children: "Current directory is not a git repository" }) });
2193
+ return /* @__PURE__ */ jsx6(TitledBox3, { borderStyle: "round", titles: ["Error"], flexGrow: 1, children: /* @__PURE__ */ jsx6(Text5, { color: "red", children: "Current directory is not a git repository" }) });
2120
2194
  }
2121
- return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", flexGrow: 1, children: [
2122
- /* @__PURE__ */ jsx5(
2195
+ return /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", flexGrow: 1, children: [
2196
+ /* @__PURE__ */ jsx6(
2123
2197
  RemotesBox,
2124
2198
  {
2125
2199
  remotes: repo.remotes,
@@ -2130,7 +2204,7 @@ ${body}`;
2130
2204
  isActive: isActive && !prPreview && focusedBox === "remotes"
2131
2205
  }
2132
2206
  ),
2133
- /* @__PURE__ */ jsx5(
2207
+ /* @__PURE__ */ jsx6(
2134
2208
  PullRequestsBox,
2135
2209
  {
2136
2210
  prs: pullRequests.prs,
@@ -2145,7 +2219,7 @@ ${body}`;
2145
2219
  isGeneratingPR
2146
2220
  }
2147
2221
  ),
2148
- /* @__PURE__ */ jsx5(
2222
+ /* @__PURE__ */ jsx6(
2149
2223
  PRDetailsBox,
2150
2224
  {
2151
2225
  pr: pullRequests.prDetails,
@@ -2154,13 +2228,13 @@ ${body}`;
2154
2228
  isActive: isActive && !prPreview && focusedBox === "details"
2155
2229
  }
2156
2230
  ),
2157
- prPreview && /* @__PURE__ */ jsx5(TitledBox3, { borderStyle: "round", titles: ["PR Preview"], borderColor: "yellow", flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", paddingX: 1, flexGrow: 1, flexBasis: 0, overflow: "hidden", children: [
2158
- /* @__PURE__ */ jsx5(Box5, { flexGrow: 1, flexBasis: 0, overflow: "hidden", children: /* @__PURE__ */ jsx5(ScrollView4, { ref: previewScrollRef, children: /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", children: [
2159
- /* @__PURE__ */ jsx5(Text5, { bold: true, children: prPreview.title }),
2160
- /* @__PURE__ */ jsx5(Text5, { children: "" }),
2161
- /* @__PURE__ */ jsx5(Text5, { children: prPreview.body })
2231
+ prPreview && /* @__PURE__ */ jsx6(TitledBox3, { borderStyle: "round", titles: ["PR Preview"], borderColor: "yellow", flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", paddingX: 1, flexGrow: 1, flexBasis: 0, overflow: "hidden", children: [
2232
+ /* @__PURE__ */ jsx6(Box6, { flexGrow: 1, flexBasis: 0, overflow: "hidden", children: /* @__PURE__ */ jsx6(ScrollView4, { ref: previewScrollRef, children: /* @__PURE__ */ jsxs5(Box6, { flexDirection: "column", children: [
2233
+ /* @__PURE__ */ jsx6(Text5, { bold: true, children: prPreview.title }),
2234
+ /* @__PURE__ */ jsx6(Text5, { children: "" }),
2235
+ /* @__PURE__ */ jsx6(Text5, { children: prPreview.body })
2162
2236
  ] }) }) }),
2163
- /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "Enter to apply, Esc to dismiss, j/k to scroll" })
2237
+ /* @__PURE__ */ jsx6(Text5, { dimColor: true, children: "Enter to apply, Esc to dismiss, j/k to scroll" })
2164
2238
  ] }) })
2165
2239
  ] });
2166
2240
  }
@@ -2171,11 +2245,11 @@ import { useEffect as useEffect10, useRef as useRef6 } from "react";
2171
2245
 
2172
2246
  // src/components/jira/LinkTicketModal.tsx
2173
2247
  import { useState as useState12 } from "react";
2174
- import { Box as Box7, Text as Text7, useInput as useInput6 } from "ink";
2248
+ import { Box as Box8, Text as Text7, useInput as useInput6 } from "ink";
2175
2249
 
2176
2250
  // src/components/ui/TextInput.tsx
2177
- import { Box as Box6, Text as Text6, useInput as useInput5 } from "ink";
2178
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2251
+ import { Box as Box7, Text as Text6, useInput as useInput5 } from "ink";
2252
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2179
2253
  function TextInput({ value, onChange, placeholder, isActive, mask }) {
2180
2254
  useInput5(
2181
2255
  (input, key) => {
@@ -2196,14 +2270,14 @@ function TextInput({ value, onChange, placeholder, isActive, mask }) {
2196
2270
  );
2197
2271
  const displayValue = mask ? "*".repeat(value.length) : value;
2198
2272
  const showPlaceholder = value.length === 0 && placeholder;
2199
- return /* @__PURE__ */ jsx6(Box6, { children: /* @__PURE__ */ jsxs6(Text6, { children: [
2200
- showPlaceholder ? /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: placeholder }) : /* @__PURE__ */ jsx6(Text6, { children: displayValue }),
2201
- isActive && /* @__PURE__ */ jsx6(Text6, { backgroundColor: "yellow", children: " " })
2273
+ return /* @__PURE__ */ jsx7(Box7, { children: /* @__PURE__ */ jsxs6(Text6, { children: [
2274
+ showPlaceholder ? /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: placeholder }) : /* @__PURE__ */ jsx7(Text6, { children: displayValue }),
2275
+ isActive && /* @__PURE__ */ jsx7(Text6, { backgroundColor: "yellow", children: " " })
2202
2276
  ] }) });
2203
2277
  }
2204
2278
 
2205
2279
  // src/components/jira/LinkTicketModal.tsx
2206
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
2280
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
2207
2281
  function LinkTicketModal({ onSubmit, onCancel, loading, error }) {
2208
2282
  const [ticketInput, setTicketInput] = useState12("");
2209
2283
  const canSubmit = ticketInput.trim().length > 0;
@@ -2220,29 +2294,29 @@ function LinkTicketModal({ onSubmit, onCancel, loading, error }) {
2220
2294
  },
2221
2295
  { isActive: !loading }
2222
2296
  );
2223
- return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
2224
- /* @__PURE__ */ jsx7(Text7, { bold: true, color: "yellow", children: "Link Jira Ticket" }),
2225
- /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Type ticket ID, Enter to submit, Esc to cancel" }),
2226
- /* @__PURE__ */ jsx7(Box7, { marginTop: 1 }),
2227
- error && /* @__PURE__ */ jsx7(Box7, { marginBottom: 1, children: /* @__PURE__ */ jsx7(Text7, { color: "red", children: error }) }),
2228
- /* @__PURE__ */ jsxs7(Box7, { children: [
2229
- /* @__PURE__ */ jsx7(Text7, { color: "blue", children: "Ticket: " }),
2230
- /* @__PURE__ */ jsx7(TextInput, { value: ticketInput, onChange: setTicketInput, placeholder: "PROJ-123", isActive: !loading })
2297
+ return /* @__PURE__ */ jsxs7(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
2298
+ /* @__PURE__ */ jsx8(Text7, { bold: true, color: "yellow", children: "Link Jira Ticket" }),
2299
+ /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "Type ticket ID, Enter to submit, Esc to cancel" }),
2300
+ /* @__PURE__ */ jsx8(Box8, { marginTop: 1 }),
2301
+ error && /* @__PURE__ */ jsx8(Box8, { marginBottom: 1, children: /* @__PURE__ */ jsx8(Text7, { color: "red", children: error }) }),
2302
+ /* @__PURE__ */ jsxs7(Box8, { children: [
2303
+ /* @__PURE__ */ jsx8(Text7, { color: "blue", children: "Ticket: " }),
2304
+ /* @__PURE__ */ jsx8(TextInput, { value: ticketInput, onChange: setTicketInput, placeholder: "PROJ-123", isActive: !loading })
2231
2305
  ] }),
2232
- loading && /* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text7, { color: "yellow", children: "Fetching ticket..." }) }),
2233
- /* @__PURE__ */ jsx7(Box7, { marginTop: 1, children: /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "Examples: PROJ-123 or https://company.atlassian.net/browse/PROJ-123" }) })
2306
+ loading && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text7, { color: "yellow", children: "Fetching ticket..." }) }),
2307
+ /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "Examples: PROJ-123 or https://company.atlassian.net/browse/PROJ-123" }) })
2234
2308
  ] });
2235
2309
  }
2236
2310
 
2237
2311
  // src/components/jira/JiraView.tsx
2238
2312
  import { TitledBox as TitledBox4 } from "@mishieck/ink-titled-box";
2239
- import { Box as Box11, Text as Text11, useInput as useInput9 } from "ink";
2313
+ import { Box as Box12, Text as Text11, useInput as useInput9 } from "ink";
2240
2314
 
2241
2315
  // src/components/jira/ChangeStatusModal.tsx
2242
2316
  import { useEffect as useEffect9, useState as useState13 } from "react";
2243
- import { Box as Box8, Text as Text8, useInput as useInput7 } from "ink";
2317
+ import { Box as Box9, Text as Text8, useInput as useInput7 } from "ink";
2244
2318
  import SelectInput from "ink-select-input";
2245
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2319
+ import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
2246
2320
  function ChangeStatusModal({ repoPath, ticketKey, currentStatus, onComplete, onCancel }) {
2247
2321
  const [transitions, setTransitions] = useState13([]);
2248
2322
  const [loading, setLoading] = useState13(true);
@@ -2310,23 +2384,23 @@ function ChangeStatusModal({ repoPath, ticketKey, currentStatus, onComplete, onC
2310
2384
  0,
2311
2385
  transitions.findIndex((t) => t.to.name === currentStatus)
2312
2386
  );
2313
- return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
2387
+ return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "yellow", paddingX: 1, paddingY: 1, children: [
2314
2388
  /* @__PURE__ */ jsxs8(Text8, { bold: true, color: "yellow", children: [
2315
2389
  "Change Status: ",
2316
2390
  ticketKey
2317
2391
  ] }),
2318
- loading && /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "Loading transitions..." }),
2319
- error && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { color: "red", children: error }) }),
2320
- !loading && !error && transitions.length === 0 && /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "No available transitions" }),
2321
- !loading && !error && transitions.length > 0 && !applying && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx8(SelectInput, { items, initialIndex, onSelect: handleSelect }) }),
2322
- applying && /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { color: "yellow", children: "Updating status..." }) }),
2323
- /* @__PURE__ */ jsx8(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "Esc to cancel" }) })
2392
+ loading && /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Loading transitions..." }),
2393
+ error && /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text8, { color: "red", children: error }) }),
2394
+ !loading && !error && transitions.length === 0 && /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "No available transitions" }),
2395
+ !loading && !error && transitions.length > 0 && !applying && /* @__PURE__ */ jsx9(Box9, { marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsx9(SelectInput, { items, initialIndex, onSelect: handleSelect }) }),
2396
+ applying && /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text8, { color: "yellow", children: "Updating status..." }) }),
2397
+ /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Esc to cancel" }) })
2324
2398
  ] });
2325
2399
  }
2326
2400
 
2327
2401
  // src/components/jira/ConfigureJiraSiteModal.tsx
2328
2402
  import { useState as useState14 } from "react";
2329
- import { Box as Box9, Text as Text9, useInput as useInput8 } from "ink";
2403
+ import { Box as Box10, Text as Text9, useInput as useInput8 } from "ink";
2330
2404
  import { ScrollView as ScrollView5 } from "ink-scroll-view";
2331
2405
 
2332
2406
  // src/lib/editor.ts
@@ -2358,7 +2432,7 @@ function openInEditor(content, filename) {
2358
2432
  }
2359
2433
 
2360
2434
  // src/components/jira/ConfigureJiraSiteModal.tsx
2361
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
2435
+ import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
2362
2436
  var MAX_VISIBLE_ITEMS = 4;
2363
2437
  function ConfigureJiraSiteModal({
2364
2438
  initialSiteUrl,
@@ -2452,26 +2526,26 @@ function ConfigureJiraSiteModal({
2452
2526
  const prefix = isSelected ? "> " : " ";
2453
2527
  const color = isSelected ? "yellow" : void 0;
2454
2528
  const displayValue = isSensitive && value ? "*".repeat(Math.min(value.length, 20)) : value;
2455
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
2529
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", children: [
2456
2530
  /* @__PURE__ */ jsxs9(Text9, { color, bold: isSelected, children: [
2457
2531
  prefix,
2458
2532
  label
2459
2533
  ] }),
2460
- value !== void 0 && /* @__PURE__ */ jsx9(Box9, { marginLeft: 4, children: /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: displayValue || "(empty - press Enter to edit)" }) })
2534
+ value !== void 0 && /* @__PURE__ */ jsx10(Box10, { marginLeft: 4, children: /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: displayValue || "(empty - press Enter to edit)" }) })
2461
2535
  ] });
2462
2536
  };
2463
2537
  if (mode === "choose") {
2464
2538
  const totalItems = existingConfigs.length + 1;
2465
2539
  const listHeight = Math.min(totalItems * 2, MAX_VISIBLE_ITEMS * 2);
2466
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [
2467
- /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: "Configure Jira Site" }),
2468
- /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Select an existing configuration or enter new credentials" }),
2469
- /* @__PURE__ */ jsx9(Box9, { marginTop: 1 }),
2470
- error && /* @__PURE__ */ jsx9(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "red", children: error }) }),
2471
- /* @__PURE__ */ jsx9(Box9, { height: listHeight, overflow: "hidden", children: /* @__PURE__ */ jsxs9(ScrollView5, { ref: scrollRef, children: [
2540
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [
2541
+ /* @__PURE__ */ jsx10(Text9, { bold: true, color: "cyan", children: "Configure Jira Site" }),
2542
+ /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "Select an existing configuration or enter new credentials" }),
2543
+ /* @__PURE__ */ jsx10(Box10, { marginTop: 1 }),
2544
+ error && /* @__PURE__ */ jsx10(Box10, { marginBottom: 1, children: /* @__PURE__ */ jsx10(Text9, { color: "red", children: error }) }),
2545
+ /* @__PURE__ */ jsx10(Box10, { height: listHeight, overflow: "hidden", children: /* @__PURE__ */ jsxs9(ScrollView5, { ref: scrollRef, children: [
2472
2546
  existingConfigs.map((config, idx) => {
2473
2547
  const isSelected = selectedExisting === idx;
2474
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
2548
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", children: [
2475
2549
  /* @__PURE__ */ jsxs9(Text9, { color: isSelected ? "yellow" : void 0, bold: isSelected, children: [
2476
2550
  isSelected ? "> " : " ",
2477
2551
  config.siteUrl
@@ -2482,7 +2556,7 @@ function ConfigureJiraSiteModal({
2482
2556
  ] })
2483
2557
  ] }, config.siteUrl + config.email);
2484
2558
  }),
2485
- /* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsxs9(
2559
+ /* @__PURE__ */ jsx10(Box10, { children: /* @__PURE__ */ jsxs9(
2486
2560
  Text9,
2487
2561
  {
2488
2562
  color: selectedExisting === existingConfigs.length ? "yellow" : void 0,
@@ -2494,41 +2568,41 @@ function ConfigureJiraSiteModal({
2494
2568
  }
2495
2569
  ) })
2496
2570
  ] }) }),
2497
- loading && /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: "Validating credentials..." }) })
2571
+ loading && /* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text9, { color: "yellow", children: "Validating credentials..." }) })
2498
2572
  ] });
2499
2573
  }
2500
- return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [
2501
- /* @__PURE__ */ jsx9(Text9, { bold: true, color: "cyan", children: "Configure Jira Site" }),
2574
+ return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1, paddingY: 1, children: [
2575
+ /* @__PURE__ */ jsx10(Text9, { bold: true, color: "cyan", children: "Configure Jira Site" }),
2502
2576
  /* @__PURE__ */ jsxs9(Text9, { dimColor: true, children: [
2503
2577
  "Up/Down to select, Enter to edit, Esc to ",
2504
2578
  hasExisting ? "go back" : "cancel"
2505
2579
  ] }),
2506
- /* @__PURE__ */ jsx9(Box9, { marginTop: 1 }),
2507
- error && /* @__PURE__ */ jsx9(Box9, { marginBottom: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "red", children: error }) }),
2580
+ /* @__PURE__ */ jsx10(Box10, { marginTop: 1 }),
2581
+ error && /* @__PURE__ */ jsx10(Box10, { marginBottom: 1, children: /* @__PURE__ */ jsx10(Text9, { color: "red", children: error }) }),
2508
2582
  renderItem("siteUrl", "Site URL (e.g., https://company.atlassian.net)", siteUrl),
2509
- /* @__PURE__ */ jsx9(Box9, { marginTop: 1 }),
2583
+ /* @__PURE__ */ jsx10(Box10, { marginTop: 1 }),
2510
2584
  renderItem("email", "Email", email),
2511
- /* @__PURE__ */ jsx9(Box9, { marginTop: 1 }),
2585
+ /* @__PURE__ */ jsx10(Box10, { marginTop: 1 }),
2512
2586
  renderItem("apiToken", "API Token", apiToken, true),
2513
- /* @__PURE__ */ jsx9(Box9, { marginTop: 1 }),
2514
- /* @__PURE__ */ jsx9(Box9, { children: /* @__PURE__ */ jsxs9(Text9, { color: selectedItem === "submit" ? "green" : void 0, bold: selectedItem === "submit", children: [
2587
+ /* @__PURE__ */ jsx10(Box10, { marginTop: 1 }),
2588
+ /* @__PURE__ */ jsx10(Box10, { children: /* @__PURE__ */ jsxs9(Text9, { color: selectedItem === "submit" ? "green" : void 0, bold: selectedItem === "submit", children: [
2515
2589
  selectedItem === "submit" ? "> " : " ",
2516
2590
  canSubmit ? "[Save Configuration]" : "[Fill all fields first]"
2517
2591
  ] }) }),
2518
- loading && /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { color: "yellow", children: "Validating credentials..." }) }),
2519
- /* @__PURE__ */ jsx9(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text9, { dimColor: true, children: "Get your API token from: https://id.atlassian.com/manage-profile/security/api-tokens" }) })
2592
+ loading && /* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text9, { color: "yellow", children: "Validating credentials..." }) }),
2593
+ /* @__PURE__ */ jsx10(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx10(Text9, { dimColor: true, children: "Get your API token from: https://id.atlassian.com/manage-profile/security/api-tokens" }) })
2520
2594
  ] });
2521
2595
  }
2522
2596
 
2523
2597
  // src/components/jira/TicketItem.tsx
2524
- import { Box as Box10, Text as Text10 } from "ink";
2525
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
2598
+ import { Box as Box11, Text as Text10 } from "ink";
2599
+ import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2526
2600
  function TicketItem({ ticketKey, summary, status, isHighlighted, isSelected }) {
2527
2601
  const prefix = isHighlighted ? "> " : isSelected ? "\u25CF " : " ";
2528
2602
  const textColor = isSelected ? "green" : void 0;
2529
- return /* @__PURE__ */ jsx10(Box10, { children: /* @__PURE__ */ jsxs10(Text10, { color: textColor, children: [
2603
+ return /* @__PURE__ */ jsx11(Box11, { children: /* @__PURE__ */ jsxs10(Text10, { color: textColor, children: [
2530
2604
  prefix,
2531
- /* @__PURE__ */ jsx10(Text10, { bold: true, color: "blue", children: ticketKey }),
2605
+ /* @__PURE__ */ jsx11(Text10, { bold: true, color: "blue", children: ticketKey }),
2532
2606
  " ",
2533
2607
  summary,
2534
2608
  status && /* @__PURE__ */ jsxs10(Text10, { dimColor: true, children: [
@@ -2540,7 +2614,7 @@ function TicketItem({ ticketKey, summary, status, isHighlighted, isSelected }) {
2540
2614
  }
2541
2615
 
2542
2616
  // src/components/jira/JiraView.tsx
2543
- import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
2617
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
2544
2618
  function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated }) {
2545
2619
  const repo = useGitRepo();
2546
2620
  const jira = useJiraTickets();
@@ -2638,13 +2712,13 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
2638
2712
  { isActive: isActive && !modal.isOpen }
2639
2713
  );
2640
2714
  if (repo.isRepo === false) {
2641
- return /* @__PURE__ */ jsx11(TitledBox4, { borderStyle: "round", titles: ["Jira"], flexShrink: 0, children: /* @__PURE__ */ jsx11(Text11, { color: "red", children: "Not a git repository" }) });
2715
+ return /* @__PURE__ */ jsx12(TitledBox4, { borderStyle: "round", titles: ["Jira"], flexShrink: 0, children: /* @__PURE__ */ jsx12(Text11, { color: "red", children: "Not a git repository" }) });
2642
2716
  }
2643
2717
  if (modal.type === "configure") {
2644
2718
  const siteUrl = repo.repoPath ? getJiraSiteUrl(repo.repoPath) : void 0;
2645
2719
  const creds = repo.repoPath ? getJiraCredentials(repo.repoPath) : { email: null, apiToken: null };
2646
2720
  const existingConfigs = getExistingJiraConfigs(repo.repoPath ?? void 0);
2647
- return /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx11(
2721
+ return /* @__PURE__ */ jsx12(Box12, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx12(
2648
2722
  ConfigureJiraSiteModal,
2649
2723
  {
2650
2724
  initialSiteUrl: siteUrl ?? void 0,
@@ -2661,7 +2735,7 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
2661
2735
  ) });
2662
2736
  }
2663
2737
  if (modal.type === "link") {
2664
- return /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx11(
2738
+ return /* @__PURE__ */ jsx12(Box12, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx12(
2665
2739
  LinkTicketModal,
2666
2740
  {
2667
2741
  onSubmit: handleLinkSubmit,
@@ -2675,7 +2749,7 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
2675
2749
  ) });
2676
2750
  }
2677
2751
  if (modal.type === "status" && repo.repoPath && repo.currentBranch && currentTicket) {
2678
- return /* @__PURE__ */ jsx11(Box11, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx11(
2752
+ return /* @__PURE__ */ jsx12(Box12, { flexDirection: "column", flexShrink: 0, children: /* @__PURE__ */ jsx12(
2679
2753
  ChangeStatusModal,
2680
2754
  {
2681
2755
  repoPath: repo.repoPath,
@@ -2688,10 +2762,10 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
2688
2762
  }
2689
2763
  const title = "[4] Jira";
2690
2764
  const borderColor = isActive ? "yellow" : void 0;
2691
- return /* @__PURE__ */ jsx11(TitledBox4, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", paddingX: 1, children: [
2692
- jira.jiraState === "not_configured" && /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "No Jira site configured" }),
2693
- jira.jiraState === "no_tickets" && /* @__PURE__ */ jsx11(Text11, { dimColor: true, children: "No tickets linked to this branch" }),
2694
- jira.jiraState === "has_tickets" && jira.tickets.map((ticket, idx) => /* @__PURE__ */ jsx11(
2765
+ return /* @__PURE__ */ jsx12(TitledBox4, { borderStyle: "round", titles: [title], borderColor, flexShrink: 0, children: /* @__PURE__ */ jsxs11(Box12, { flexDirection: "column", paddingX: 1, children: [
2766
+ jira.jiraState === "not_configured" && /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "No Jira site configured" }),
2767
+ jira.jiraState === "no_tickets" && /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "No tickets linked to this branch" }),
2768
+ jira.jiraState === "has_tickets" && jira.tickets.map((ticket, idx) => /* @__PURE__ */ jsx12(
2695
2769
  TicketItem,
2696
2770
  {
2697
2771
  ticketKey: ticket.key,
@@ -2706,15 +2780,16 @@ function JiraView({ isActive, onModalChange, onJiraStateChange, onLogUpdated })
2706
2780
 
2707
2781
  // src/components/logs/LogsView.tsx
2708
2782
  import { useEffect as useEffect12 } from "react";
2709
- import { Box as Box14, useInput as useInput12 } from "ink";
2783
+ import { Box as Box15, useInput as useInput12 } from "ink";
2710
2784
 
2711
2785
  // src/components/logs/LogViewerBox.tsx
2712
2786
  import { useEffect as useEffect11, useRef as useRef7, useState as useState15 } from "react";
2713
2787
  import { TitledBox as TitledBox5 } from "@mishieck/ink-titled-box";
2714
- import { Box as Box12, Text as Text12, useInput as useInput10 } from "ink";
2788
+ import { Box as Box13, Text as Text12, useInput as useInput10 } from "ink";
2715
2789
  import { ScrollView as ScrollView6 } from "ink-scroll-view";
2790
+ import Spinner2 from "ink-spinner";
2716
2791
  import TextInput2 from "ink-text-input";
2717
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
2792
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
2718
2793
  function LogViewerBox({ date, content, isActive, onRefresh, onLogCreated }) {
2719
2794
  const scrollRef = useRef7(null);
2720
2795
  const [isInputMode, setIsInputMode] = useState15(false);
@@ -2810,14 +2885,14 @@ ${value.trim()}
2810
2885
  setIsInputMode(false);
2811
2886
  onRefresh();
2812
2887
  };
2813
- return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", flexGrow: 1, children: [
2814
- /* @__PURE__ */ jsx12(TitledBox5, { borderStyle: "round", titles: [displayTitle], borderColor, flexGrow: 1, children: /* @__PURE__ */ jsx12(Box12, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx12(ScrollView6, { ref: scrollRef, children: /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingX: 1, children: [
2815
- !date && /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "Select a log file to view" }),
2816
- date && content === null && /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "Log file not found" }),
2817
- date && content !== null && content.trim() === "" && /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "Empty log file" }),
2818
- date && content && content.trim() !== "" && /* @__PURE__ */ jsx12(Markdown, { children: content })
2888
+ return /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", flexGrow: 1, children: [
2889
+ /* @__PURE__ */ jsx13(TitledBox5, { borderStyle: "round", titles: [displayTitle], borderColor, flexGrow: 1, children: /* @__PURE__ */ jsx13(Box13, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx13(ScrollView6, { ref: scrollRef, children: /* @__PURE__ */ jsxs12(Box13, { flexDirection: "column", paddingX: 1, children: [
2890
+ !date && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Select a log file to view" }),
2891
+ date && content === null && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Log file not found" }),
2892
+ date && content !== null && content.trim() === "" && /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Empty log file" }),
2893
+ date && content && content.trim() !== "" && /* @__PURE__ */ jsx13(Markdown, { children: content })
2819
2894
  ] }) }) }) }),
2820
- isInputMode && /* @__PURE__ */ jsx12(TitledBox5, { borderStyle: "round", titles: ["Add Entry"], borderColor: "yellow", children: /* @__PURE__ */ jsx12(Box12, { paddingX: 1, children: /* @__PURE__ */ jsx12(
2895
+ isInputMode && /* @__PURE__ */ jsx13(TitledBox5, { borderStyle: "round", titles: ["Add Entry"], borderColor: "yellow", children: /* @__PURE__ */ jsx13(Box13, { paddingX: 1, children: /* @__PURE__ */ jsx13(
2821
2896
  TextInput2,
2822
2897
  {
2823
2898
  value: inputValue,
@@ -2825,19 +2900,22 @@ ${value.trim()}
2825
2900
  onSubmit: handleInputSubmit
2826
2901
  }
2827
2902
  ) }) }),
2828
- isGeneratingStandup && /* @__PURE__ */ jsx12(TitledBox5, { borderStyle: "round", titles: ["Standup Notes"], borderColor: "yellow", children: /* @__PURE__ */ jsxs12(Box12, { paddingX: 1, flexDirection: "column", children: [
2829
- /* @__PURE__ */ jsx12(Text12, { color: "yellow", children: "Generating standup notes..." }),
2830
- /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "Press Esc to cancel" })
2903
+ isGeneratingStandup && /* @__PURE__ */ jsx13(TitledBox5, { borderStyle: "round", titles: ["Standup Notes"], borderColor: "yellow", children: /* @__PURE__ */ jsxs12(Box13, { paddingX: 1, flexDirection: "column", children: [
2904
+ /* @__PURE__ */ jsxs12(Text12, { color: "yellow", children: [
2905
+ /* @__PURE__ */ jsx13(Spinner2, { type: "dots" }),
2906
+ " Generating standup notes..."
2907
+ ] }),
2908
+ /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Press Esc to cancel" })
2831
2909
  ] }) }),
2832
- standupResult && /* @__PURE__ */ jsx12(
2910
+ standupResult && /* @__PURE__ */ jsx13(
2833
2911
  TitledBox5,
2834
2912
  {
2835
2913
  borderStyle: "round",
2836
2914
  titles: ["Standup Notes"],
2837
2915
  borderColor: standupResult.type === "error" ? "red" : "green",
2838
- children: /* @__PURE__ */ jsxs12(Box12, { paddingX: 1, flexDirection: "column", children: [
2839
- standupResult.type === "error" ? /* @__PURE__ */ jsx12(Text12, { color: "red", children: standupResult.message }) : /* @__PURE__ */ jsx12(Markdown, { children: standupResult.message }),
2840
- /* @__PURE__ */ jsx12(Text12, { dimColor: true, children: "Press Esc to dismiss" })
2916
+ children: /* @__PURE__ */ jsxs12(Box13, { paddingX: 1, flexDirection: "column", children: [
2917
+ standupResult.type === "error" ? /* @__PURE__ */ jsx13(Text12, { color: "red", children: standupResult.message }) : /* @__PURE__ */ jsx13(Markdown, { children: standupResult.message }),
2918
+ /* @__PURE__ */ jsx13(Text12, { dimColor: true, children: "Press Esc to dismiss" })
2841
2919
  ] })
2842
2920
  }
2843
2921
  )
@@ -2846,9 +2924,9 @@ ${value.trim()}
2846
2924
 
2847
2925
  // src/components/logs/LogsHistoryBox.tsx
2848
2926
  import { TitledBox as TitledBox6 } from "@mishieck/ink-titled-box";
2849
- import { Box as Box13, Text as Text13, useInput as useInput11 } from "ink";
2927
+ import { Box as Box14, Text as Text13, useInput as useInput11 } from "ink";
2850
2928
  import { ScrollView as ScrollView7 } from "ink-scroll-view";
2851
- import { jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
2929
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2852
2930
  function LogsHistoryBox({
2853
2931
  logFiles,
2854
2932
  selectedDate,
@@ -2878,28 +2956,28 @@ function LogsHistoryBox({
2878
2956
  },
2879
2957
  { isActive }
2880
2958
  );
2881
- return /* @__PURE__ */ jsx13(TitledBox6, { borderStyle: "round", titles: [title], borderColor, height: 5, children: /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
2882
- logFiles.length === 0 && /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: "No logs yet" }),
2883
- logFiles.length > 0 && /* @__PURE__ */ jsx13(ScrollView7, { ref: scrollRef, children: logFiles.map((file, idx) => {
2959
+ return /* @__PURE__ */ jsx14(TitledBox6, { borderStyle: "round", titles: [title], borderColor, height: 5, children: /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", paddingX: 1, flexGrow: 1, overflow: "hidden", children: [
2960
+ logFiles.length === 0 && /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: "No logs yet" }),
2961
+ logFiles.length > 0 && /* @__PURE__ */ jsx14(ScrollView7, { ref: scrollRef, children: logFiles.map((file, idx) => {
2884
2962
  const isHighlighted = idx === highlightedIndex;
2885
2963
  const isSelected = file.date === selectedDate;
2886
2964
  const cursor = isHighlighted ? ">" : " ";
2887
2965
  const indicator = isSelected ? " *" : "";
2888
- return /* @__PURE__ */ jsxs13(Box13, { children: [
2966
+ return /* @__PURE__ */ jsxs13(Box14, { children: [
2889
2967
  /* @__PURE__ */ jsxs13(Text13, { color: isHighlighted ? "yellow" : void 0, children: [
2890
2968
  cursor,
2891
2969
  " "
2892
2970
  ] }),
2893
- /* @__PURE__ */ jsx13(Text13, { color: file.isToday ? "green" : void 0, bold: file.isToday, children: file.date }),
2894
- file.isToday && /* @__PURE__ */ jsx13(Text13, { color: "green", children: " (today)" }),
2895
- /* @__PURE__ */ jsx13(Text13, { dimColor: true, children: indicator })
2971
+ /* @__PURE__ */ jsx14(Text13, { color: file.isToday ? "green" : void 0, bold: file.isToday, children: file.date }),
2972
+ file.isToday && /* @__PURE__ */ jsx14(Text13, { color: "green", children: " (today)" }),
2973
+ /* @__PURE__ */ jsx14(Text13, { dimColor: true, children: indicator })
2896
2974
  ] }, file.date);
2897
2975
  }) })
2898
2976
  ] }) });
2899
2977
  }
2900
2978
 
2901
2979
  // src/components/logs/LogsView.tsx
2902
- import { jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
2980
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
2903
2981
  function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
2904
2982
  const logs = useLogs();
2905
2983
  useEffect12(() => {
@@ -2914,8 +2992,8 @@ function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
2914
2992
  },
2915
2993
  { isActive }
2916
2994
  );
2917
- return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", flexGrow: 1, children: [
2918
- /* @__PURE__ */ jsx14(
2995
+ return /* @__PURE__ */ jsxs14(Box15, { flexDirection: "column", flexGrow: 1, children: [
2996
+ /* @__PURE__ */ jsx15(
2919
2997
  LogsHistoryBox,
2920
2998
  {
2921
2999
  logFiles: logs.logFiles,
@@ -2926,7 +3004,7 @@ function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
2926
3004
  isActive: isActive && focusedBox === "history"
2927
3005
  }
2928
3006
  ),
2929
- /* @__PURE__ */ jsx14(
3007
+ /* @__PURE__ */ jsx15(
2930
3008
  LogViewerBox,
2931
3009
  {
2932
3010
  date: logs.selectedDate,
@@ -2940,8 +3018,8 @@ function LogsView({ isActive, refreshKey, focusedBox, onFocusedBoxChange }) {
2940
3018
  }
2941
3019
 
2942
3020
  // src/components/ui/KeybindingsBar.tsx
2943
- import { Box as Box15, Text as Text14 } from "ink";
2944
- import { jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
3021
+ import { Box as Box16, Text as Text14 } from "ink";
3022
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
2945
3023
  var globalBindings = [
2946
3024
  { key: "1-4", label: "Focus" },
2947
3025
  { key: "j/k", label: "Navigate" },
@@ -2951,14 +3029,14 @@ var modalBindings = [{ key: "Esc", label: "Cancel" }];
2951
3029
  var DUCK_ASCII = "<(')___";
2952
3030
  function KeybindingsBar({ contextBindings = [], modalOpen = false, duck }) {
2953
3031
  const allBindings = modalOpen ? [...contextBindings, ...modalBindings] : [...contextBindings, ...globalBindings];
2954
- return /* @__PURE__ */ jsxs15(Box15, { flexShrink: 0, paddingX: 1, gap: 2, children: [
2955
- allBindings.map((binding) => /* @__PURE__ */ jsxs15(Box15, { gap: 1, children: [
2956
- /* @__PURE__ */ jsx15(Text14, { bold: true, color: binding.color ?? "yellow", children: binding.key }),
2957
- /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: binding.label })
3032
+ return /* @__PURE__ */ jsxs15(Box16, { flexShrink: 0, paddingX: 1, gap: 2, children: [
3033
+ allBindings.map((binding) => /* @__PURE__ */ jsxs15(Box16, { gap: 1, children: [
3034
+ /* @__PURE__ */ jsx16(Text14, { bold: true, color: binding.color ?? "yellow", children: binding.key }),
3035
+ /* @__PURE__ */ jsx16(Text14, { dimColor: true, children: binding.label })
2958
3036
  ] }, binding.key)),
2959
- (duck == null ? void 0 : duck.visible) && /* @__PURE__ */ jsxs15(Box15, { flexGrow: 1, justifyContent: "flex-end", gap: 1, children: [
2960
- /* @__PURE__ */ jsx15(Text14, { children: DUCK_ASCII }),
2961
- /* @__PURE__ */ jsx15(Text14, { dimColor: true, children: duck.message })
3037
+ (duck == null ? void 0 : duck.visible) && /* @__PURE__ */ jsxs15(Box16, { flexGrow: 1, justifyContent: "flex-end", gap: 1, children: [
3038
+ /* @__PURE__ */ jsx16(Text14, { children: DUCK_ASCII }),
3039
+ /* @__PURE__ */ jsx16(Text14, { dimColor: true, children: duck.message })
2962
3040
  ] })
2963
3041
  ] });
2964
3042
  }
@@ -3025,7 +3103,7 @@ function computeKeybindings(focusedView, state) {
3025
3103
  }
3026
3104
 
3027
3105
  // src/app.tsx
3028
- import { jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
3106
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
3029
3107
  function App() {
3030
3108
  const { exit } = useApp();
3031
3109
  const [focusedView, setFocusedView] = useState16("github");
@@ -3074,10 +3152,10 @@ function App() {
3074
3152
  },
3075
3153
  { isActive: !modalOpen }
3076
3154
  );
3077
- return /* @__PURE__ */ jsxs16(Box16, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: [
3078
- /* @__PURE__ */ jsxs16(Box16, { flexGrow: 1, flexDirection: "row", columnGap: 1, children: [
3079
- /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: [
3080
- /* @__PURE__ */ jsx16(
3155
+ return /* @__PURE__ */ jsxs16(Box17, { flexGrow: 1, flexDirection: "column", overflow: "hidden", children: [
3156
+ /* @__PURE__ */ jsxs16(Box17, { flexGrow: 1, flexDirection: "row", columnGap: 1, children: [
3157
+ /* @__PURE__ */ jsxs16(Box17, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: [
3158
+ /* @__PURE__ */ jsx17(
3081
3159
  GitHubView,
3082
3160
  {
3083
3161
  isActive: focusedView === "github",
@@ -3085,7 +3163,7 @@ function App() {
3085
3163
  onLogUpdated: handleLogUpdated
3086
3164
  }
3087
3165
  ),
3088
- /* @__PURE__ */ jsx16(
3166
+ /* @__PURE__ */ jsx17(
3089
3167
  JiraView,
3090
3168
  {
3091
3169
  isActive: focusedView === "jira",
@@ -3095,7 +3173,7 @@ function App() {
3095
3173
  }
3096
3174
  )
3097
3175
  ] }),
3098
- /* @__PURE__ */ jsx16(Box16, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsx16(
3176
+ /* @__PURE__ */ jsx17(Box17, { flexDirection: "column", flexGrow: 1, flexBasis: 0, children: /* @__PURE__ */ jsx17(
3099
3177
  LogsView,
3100
3178
  {
3101
3179
  isActive: focusedView === "logs",
@@ -3105,7 +3183,7 @@ function App() {
3105
3183
  }
3106
3184
  ) })
3107
3185
  ] }),
3108
- /* @__PURE__ */ jsx16(
3186
+ /* @__PURE__ */ jsx17(
3109
3187
  KeybindingsBar,
3110
3188
  {
3111
3189
  contextBindings: keybindings,
@@ -3121,8 +3199,8 @@ import { render as inkRender } from "ink";
3121
3199
 
3122
3200
  // src/lib/Screen.tsx
3123
3201
  import { useCallback as useCallback10, useEffect as useEffect13, useState as useState17 } from "react";
3124
- import { Box as Box17, useStdout as useStdout2 } from "ink";
3125
- import { jsx as jsx17 } from "react/jsx-runtime";
3202
+ import { Box as Box18, useStdout as useStdout2 } from "ink";
3203
+ import { jsx as jsx18 } from "react/jsx-runtime";
3126
3204
  function Screen({ children }) {
3127
3205
  const { stdout } = useStdout2();
3128
3206
  const getSize = useCallback10(() => ({ height: stdout.rows, width: stdout.columns }), [stdout]);
@@ -3134,17 +3212,17 @@ function Screen({ children }) {
3134
3212
  stdout.off("resize", onResize);
3135
3213
  };
3136
3214
  }, [stdout, getSize]);
3137
- return /* @__PURE__ */ jsx17(Box17, { height: size.height, width: size.width, children });
3215
+ return /* @__PURE__ */ jsx18(Box18, { height: size.height, width: size.width, children });
3138
3216
  }
3139
3217
 
3140
3218
  // src/lib/render.tsx
3141
- import { jsx as jsx18 } from "react/jsx-runtime";
3219
+ import { jsx as jsx19 } from "react/jsx-runtime";
3142
3220
  var ENTER_ALT_BUFFER = "\x1B[?1049h";
3143
3221
  var EXIT_ALT_BUFFER = "\x1B[?1049l";
3144
3222
  var CLEAR_SCREEN = "\x1B[2J\x1B[H";
3145
3223
  function render(node, options) {
3146
3224
  process.stdout.write(ENTER_ALT_BUFFER + CLEAR_SCREEN);
3147
- const element = /* @__PURE__ */ jsx18(Screen, { children: node });
3225
+ const element = /* @__PURE__ */ jsx19(Screen, { children: node });
3148
3226
  const instance = inkRender(element, options);
3149
3227
  setImmediate(() => instance.rerender(element));
3150
3228
  const cleanup = () => process.stdout.write(EXIT_ALT_BUFFER);
@@ -3165,7 +3243,7 @@ function render(node, options) {
3165
3243
  }
3166
3244
 
3167
3245
  // src/cli.tsx
3168
- import { jsx as jsx19 } from "react/jsx-runtime";
3246
+ import { jsx as jsx20 } from "react/jsx-runtime";
3169
3247
  var cli = meow(
3170
3248
  `
3171
3249
  Usage
@@ -3198,4 +3276,4 @@ if (cli.flags.cwd) {
3198
3276
  process.exit(1);
3199
3277
  }
3200
3278
  }
3201
- render(/* @__PURE__ */ jsx19(App, {}));
3279
+ render(/* @__PURE__ */ jsx20(App, {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clairo",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,6 +27,7 @@
27
27
  "ink-link": "^5.0.0",
28
28
  "ink-scroll-view": "^0.3.5",
29
29
  "ink-select-input": "^6.2.0",
30
+ "ink-spinner": "^5.0.0",
30
31
  "ink-text-input": "^6.0.0",
31
32
  "marked": "^17.0.1",
32
33
  "meow": "^11.0.0",