indusagi 0.13.1 → 0.13.3

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.13.3]
4
+
5
+ ### Changed
6
+ - **TaskPanel Queued-Messages Hint**: the queued-messages footer now reads "Ctrl+X runs the newest queued message now · Alt+Up restores it to the prompt", documenting the console's new steer chord alongside the existing dequeue chord.
7
+ - **Version Bump**: Updated package version to `0.13.3`.
8
+
9
+ ## [0.13.2]
10
+
11
+ ### Added
12
+ - **Saffron Tool-Event Grammar**: `react-ink` `ToolEventBlock` now renders every tool call/result with a colour-keyed `●` status dot (running → accent, success → green, error → red), a **bold** neutral tool name, a dim `(summary)`, and a `└` elbow connector on result lines — replacing the old `>` / `=` / `!` markers.
13
+ - **Collapsed / Expanded Tool Output**: new `COLLAPSED_CONTENT_LINES` (2) and `EXPANDED_CONTENT_LINES` (20) exports. A collapsed tool reads as a tight 2–3 line block (`● Action` + `└ summary` + `… N more line(s)`); expanding lifts the cap to ~20 lines. The overflow marker takes an optional `moreHint` prop (e.g. `ctrl+o to expand`).
14
+
15
+ ### Changed
16
+ - **Diff Tool Header**: `ToolResultBlock` shows the edit/write change-summary as a `└` line above the colored diff block (collapsed cap `0`→`1`).
17
+ - **TaskPanel**: the "Tool Activity" header renders only when there are tool rows — an empty list shows nothing.
18
+ - **Version Bump**: Updated package version to `0.13.2`.
19
+
3
20
  ## [0.13.1]
4
21
 
5
22
  ### Added
package/dist/agent.js CHANGED
@@ -1476,6 +1476,40 @@ var MODELS = {
1476
1476
  contextWindow: 2e5,
1477
1477
  maxTokens: 8192
1478
1478
  },
1479
+ "claude-opus-4-7": {
1480
+ id: "claude-opus-4-7",
1481
+ name: "Claude Opus 4.7",
1482
+ api: "anthropic-messages",
1483
+ provider: "anthropic",
1484
+ baseUrl: "https://api.anthropic.com",
1485
+ reasoning: true,
1486
+ input: ["text", "image"],
1487
+ cost: {
1488
+ input: 5,
1489
+ output: 25,
1490
+ cacheRead: 0.5,
1491
+ cacheWrite: 6.25
1492
+ },
1493
+ contextWindow: 1e6,
1494
+ maxTokens: 128e3
1495
+ },
1496
+ "claude-opus-4-8": {
1497
+ id: "claude-opus-4-8",
1498
+ name: "Claude Opus 4.8",
1499
+ api: "anthropic-messages",
1500
+ provider: "anthropic",
1501
+ baseUrl: "https://api.anthropic.com",
1502
+ reasoning: true,
1503
+ input: ["text", "image"],
1504
+ cost: {
1505
+ input: 5,
1506
+ output: 25,
1507
+ cacheRead: 0.5,
1508
+ cacheWrite: 6.25
1509
+ },
1510
+ contextWindow: 1e6,
1511
+ maxTokens: 128e3
1512
+ },
1479
1513
  "claude-sonnet-4-0": {
1480
1514
  id: "claude-sonnet-4-0",
1481
1515
  name: "Claude Sonnet 4 (latest)",
@@ -12005,7 +12039,7 @@ var MODELS = {
12005
12039
  cacheWrite: 0
12006
12040
  },
12007
12041
  contextWindow: 64e3,
12008
- maxTokens: 8192
12042
+ maxTokens: 4096
12009
12043
  },
12010
12044
  "sarvam-105b": {
12011
12045
  id: "sarvam-105b",
@@ -12022,7 +12056,7 @@ var MODELS = {
12022
12056
  cacheWrite: 0
12023
12057
  },
12024
12058
  contextWindow: 128e3,
12025
- maxTokens: 8192
12059
+ maxTokens: 4096
12026
12060
  },
12027
12061
  "sarvam-m": {
12028
12062
  id: "sarvam-m",
@@ -12039,7 +12073,7 @@ var MODELS = {
12039
12073
  cacheWrite: 0
12040
12074
  },
12041
12075
  contextWindow: 32e3,
12042
- maxTokens: 8192
12076
+ maxTokens: 4096
12043
12077
  }
12044
12078
  },
12045
12079
  // Krutrim — OpenAI-compatible chat completions API
package/dist/ai.js CHANGED
@@ -1600,6 +1600,40 @@ var MODELS = {
1600
1600
  contextWindow: 2e5,
1601
1601
  maxTokens: 8192
1602
1602
  },
1603
+ "claude-opus-4-7": {
1604
+ id: "claude-opus-4-7",
1605
+ name: "Claude Opus 4.7",
1606
+ api: "anthropic-messages",
1607
+ provider: "anthropic",
1608
+ baseUrl: "https://api.anthropic.com",
1609
+ reasoning: true,
1610
+ input: ["text", "image"],
1611
+ cost: {
1612
+ input: 5,
1613
+ output: 25,
1614
+ cacheRead: 0.5,
1615
+ cacheWrite: 6.25
1616
+ },
1617
+ contextWindow: 1e6,
1618
+ maxTokens: 128e3
1619
+ },
1620
+ "claude-opus-4-8": {
1621
+ id: "claude-opus-4-8",
1622
+ name: "Claude Opus 4.8",
1623
+ api: "anthropic-messages",
1624
+ provider: "anthropic",
1625
+ baseUrl: "https://api.anthropic.com",
1626
+ reasoning: true,
1627
+ input: ["text", "image"],
1628
+ cost: {
1629
+ input: 5,
1630
+ output: 25,
1631
+ cacheRead: 0.5,
1632
+ cacheWrite: 6.25
1633
+ },
1634
+ contextWindow: 1e6,
1635
+ maxTokens: 128e3
1636
+ },
1603
1637
  "claude-sonnet-4-0": {
1604
1638
  id: "claude-sonnet-4-0",
1605
1639
  name: "Claude Sonnet 4 (latest)",
@@ -12129,7 +12163,7 @@ var MODELS = {
12129
12163
  cacheWrite: 0
12130
12164
  },
12131
12165
  contextWindow: 64e3,
12132
- maxTokens: 8192
12166
+ maxTokens: 4096
12133
12167
  },
12134
12168
  "sarvam-105b": {
12135
12169
  id: "sarvam-105b",
@@ -12146,7 +12180,7 @@ var MODELS = {
12146
12180
  cacheWrite: 0
12147
12181
  },
12148
12182
  contextWindow: 128e3,
12149
- maxTokens: 8192
12183
+ maxTokens: 4096
12150
12184
  },
12151
12185
  "sarvam-m": {
12152
12186
  id: "sarvam-m",
@@ -12163,7 +12197,7 @@ var MODELS = {
12163
12197
  cacheWrite: 0
12164
12198
  },
12165
12199
  contextWindow: 32e3,
12166
- maxTokens: 8192
12200
+ maxTokens: 4096
12167
12201
  }
12168
12202
  },
12169
12203
  // Krutrim — OpenAI-compatible chat completions API
package/dist/cli.js CHANGED
@@ -277,6 +277,40 @@ var MODEL_CARDS = [
277
277
  cacheWritePerMTok: 18.75
278
278
  }
279
279
  },
280
+ {
281
+ id: "claude-opus-4-7",
282
+ provider: "anthropic",
283
+ api: "anthropic-messages",
284
+ displayName: "Claude Opus 4.7",
285
+ contextWindow: 1e6,
286
+ maxOutputTokens: 128e3,
287
+ modalities: ["text", "image"],
288
+ reasoning: true,
289
+ cost: {
290
+ // approximate — flagship tier
291
+ inputPerMTok: 5,
292
+ outputPerMTok: 25,
293
+ cacheReadPerMTok: 0.5,
294
+ cacheWritePerMTok: 6.25
295
+ }
296
+ },
297
+ {
298
+ id: "claude-opus-4-8",
299
+ provider: "anthropic",
300
+ api: "anthropic-messages",
301
+ displayName: "Claude Opus 4.8",
302
+ contextWindow: 1e6,
303
+ maxOutputTokens: 128e3,
304
+ modalities: ["text", "image"],
305
+ reasoning: true,
306
+ cost: {
307
+ // approximate — flagship tier
308
+ inputPerMTok: 5,
309
+ outputPerMTok: 25,
310
+ cacheReadPerMTok: 0.5,
311
+ cacheWritePerMTok: 6.25
312
+ }
313
+ },
280
314
  {
281
315
  id: "claude-sonnet-4",
282
316
  provider: "anthropic",
@@ -10430,19 +10464,22 @@ function describeToolResult(message, showImages, args, theme) {
10430
10464
 
10431
10465
  // src/react-ink/components/ToolEventBlock.tsx
10432
10466
  import stripAnsi5 from "strip-ansi";
10433
- function statusMarker(status) {
10467
+ var STATUS_DOT = "\u25CF";
10468
+ var COLLAPSED_CONTENT_LINES = 2;
10469
+ var EXPANDED_CONTENT_LINES = 20;
10470
+ function contentConnector(isFirst) {
10471
+ return isFirst ? "\u2514 " : " ";
10472
+ }
10473
+ function statusColorKey(status) {
10434
10474
  switch (status) {
10435
10475
  case "error":
10436
- return "!";
10476
+ return "error";
10437
10477
  case "success":
10438
- return "=";
10478
+ return "success";
10439
10479
  default:
10440
- return ">";
10480
+ return "accent";
10441
10481
  }
10442
10482
  }
10443
- function statusColorKey(status) {
10444
- return status === "error" ? "error" : "text";
10445
- }
10446
10483
  function plainToolText(text) {
10447
10484
  return stripAnsi5(text);
10448
10485
  }
@@ -10478,7 +10515,8 @@ function ToolEventBlock({
10478
10515
  emptyText,
10479
10516
  indent = 0,
10480
10517
  marginBottom = 1,
10481
- maxContentLines = 10,
10518
+ maxContentLines = COLLAPSED_CONTENT_LINES,
10519
+ moreHint,
10482
10520
  preformatted = false,
10483
10521
  showSummaryInline = false,
10484
10522
  showTitle = true,
@@ -10498,21 +10536,22 @@ function ToolEventBlock({
10498
10536
  ...detailLines.map((text) => ({ kind: "detail", text }))
10499
10537
  ];
10500
10538
  const { visibleLines, hiddenLineCount } = clampContentLines(combinedLines, maxContentLines);
10539
+ const contentIndent = showTitle ? 2 : 0;
10501
10540
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom, marginLeft: indent, children: [
10502
10541
  showTitle ? /* @__PURE__ */ jsxs(Box, { children: [
10503
- /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), plainToolText(`${statusMarker(status)} `)) }),
10504
- /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), plainToolText(title)) }),
10542
+ /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), `${STATUS_DOT} `) }),
10543
+ /* @__PURE__ */ jsx(Text, { bold: true, children: theme.color("text", plainToolText(title)) }),
10505
10544
  showSummaryInline && normalizedSummary ? /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(` (${normalizedSummary})`)) }) : null
10506
10545
  ] }) : null,
10507
- visibleLines.map((line, index) => /* @__PURE__ */ jsx(
10508
- Box,
10509
- {
10510
- marginLeft: line.kind === "response" ? showTitle ? 2 : 0 : showTitle ? 4 : 2,
10511
- children: preformatted ? /* @__PURE__ */ jsx(Text, { children: line.text }) : /* @__PURE__ */ jsx(Text, { children: theme.color("text", plainToolText(line.text)) })
10512
- },
10513
- `${line.kind}:${index}:${stripAnsi5(line.text)}`
10514
- )),
10515
- hiddenLineCount > 0 ? /* @__PURE__ */ jsx(Box, { marginLeft: showTitle ? 4 : 2, children: /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(`... ${hiddenLineCount} more line(s)`)) }) }) : null
10546
+ visibleLines.map((line, index) => /* @__PURE__ */ jsxs(Box, { marginLeft: contentIndent, children: [
10547
+ /* @__PURE__ */ jsx(Text, { children: theme.dim(contentConnector(index === 0)) }),
10548
+ preformatted ? /* @__PURE__ */ jsx(Text, { children: line.text }) : /* @__PURE__ */ jsx(Text, { children: theme.color("text", plainToolText(line.text)) })
10549
+ ] }, `${line.kind}:${index}:${stripAnsi5(line.text)}`)),
10550
+ hiddenLineCount > 0 ? /* @__PURE__ */ jsxs(Box, { marginLeft: contentIndent, children: [
10551
+ /* @__PURE__ */ jsx(Text, { children: theme.dim(contentConnector(visibleLines.length === 0)) }),
10552
+ /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(`\u2026 ${hiddenLineCount} more line(s)`)) }),
10553
+ moreHint ? /* @__PURE__ */ jsx(Text, { children: theme.dim(plainToolText(` \xB7 ${moreHint}`)) }) : null
10554
+ ] }) : null
10516
10555
  ] });
10517
10556
  }
10518
10557
 
@@ -10608,7 +10647,7 @@ function ToolResultBlock({ expanded = false, message, nested = false, showImages
10608
10647
  emptyText: descriptor.emptyText,
10609
10648
  indent,
10610
10649
  marginBottom: 0,
10611
- maxContentLines: 0,
10650
+ maxContentLines: 1,
10612
10651
  showSummaryInline: false,
10613
10652
  showTitle: !nested,
10614
10653
  status: message.isError ? "error" : "success",
@@ -10627,7 +10666,8 @@ function ToolResultBlock({ expanded = false, message, nested = false, showImages
10627
10666
  emptyText: descriptor.emptyText,
10628
10667
  indent,
10629
10668
  marginBottom: 0,
10630
- maxContentLines: expanded ? Number.MAX_SAFE_INTEGER : 10,
10669
+ maxContentLines: expanded ? EXPANDED_CONTENT_LINES : COLLAPSED_CONTENT_LINES,
10670
+ moreHint: expanded ? "ctrl+o to collapse" : "ctrl+o to expand",
10631
10671
  preformatted: descriptor.preformatted,
10632
10672
  showSummaryInline: false,
10633
10673
  showTitle: !nested,
@@ -10892,7 +10932,7 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
10892
10932
  return null;
10893
10933
  }
10894
10934
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, marginTop: 1, children: [
10895
- /* @__PURE__ */ jsx(Text, { children: theme.color("accent", `Tool Activity${recent.length > 0 ? ` ${recent.length}` : ""}`) }),
10935
+ recent.length > 0 ? /* @__PURE__ */ jsx(Text, { children: theme.color("accent", `Tool Activity ${recent.length}`) }) : null,
10896
10936
  recent.map((tool) => {
10897
10937
  const descriptor = describeToolExecution(tool);
10898
10938
  return /* @__PURE__ */ jsx(
@@ -10902,7 +10942,8 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
10902
10942
  emptyText: descriptor.emptyText,
10903
10943
  indent: 1,
10904
10944
  marginBottom: 0,
10905
- maxContentLines: expandToolOutputs ? Number.MAX_SAFE_INTEGER : 10,
10945
+ maxContentLines: expandToolOutputs ? EXPANDED_CONTENT_LINES : COLLAPSED_CONTENT_LINES,
10946
+ moreHint: expandToolOutputs ? "ctrl+o to collapse" : "ctrl+o to expand",
10906
10947
  showSummaryInline: true,
10907
10948
  status: tool.status,
10908
10949
  summary: descriptor.summary,
@@ -10918,7 +10959,7 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
10918
10959
  theme.muted(` ${message.mode === "steer" ? "Steering" : "Follow-up"}: `),
10919
10960
  message.text.length > 90 ? `${message.text.slice(0, 87)}...` : message.text
10920
10961
  ] }, message.id)),
10921
- /* @__PURE__ */ jsx(Text, { children: theme.muted(" Alt+Up restores queued messages to the prompt") })
10962
+ /* @__PURE__ */ jsx(Text, { children: theme.muted(" Ctrl+X runs the newest queued message now \xB7 Alt+Up restores it to the prompt") })
10922
10963
  ] }) : snapshot.pendingMessageCount > 0 ? /* @__PURE__ */ jsx(Text, { children: theme.muted(`${snapshot.pendingMessageCount} queued message(s) waiting for the next turn`) }) : null
10923
10964
  ] });
10924
10965
  }
package/dist/index.js CHANGED
@@ -60,6 +60,40 @@ var MODEL_CARDS = [
60
60
  cacheWritePerMTok: 18.75
61
61
  }
62
62
  },
63
+ {
64
+ id: "claude-opus-4-7",
65
+ provider: "anthropic",
66
+ api: "anthropic-messages",
67
+ displayName: "Claude Opus 4.7",
68
+ contextWindow: 1e6,
69
+ maxOutputTokens: 128e3,
70
+ modalities: ["text", "image"],
71
+ reasoning: true,
72
+ cost: {
73
+ // approximate — flagship tier
74
+ inputPerMTok: 5,
75
+ outputPerMTok: 25,
76
+ cacheReadPerMTok: 0.5,
77
+ cacheWritePerMTok: 6.25
78
+ }
79
+ },
80
+ {
81
+ id: "claude-opus-4-8",
82
+ provider: "anthropic",
83
+ api: "anthropic-messages",
84
+ displayName: "Claude Opus 4.8",
85
+ contextWindow: 1e6,
86
+ maxOutputTokens: 128e3,
87
+ modalities: ["text", "image"],
88
+ reasoning: true,
89
+ cost: {
90
+ // approximate — flagship tier
91
+ inputPerMTok: 5,
92
+ outputPerMTok: 25,
93
+ cacheReadPerMTok: 0.5,
94
+ cacheWritePerMTok: 6.25
95
+ }
96
+ },
63
97
  {
64
98
  id: "claude-sonnet-4",
65
99
  provider: "anthropic",
@@ -14759,19 +14793,22 @@ function describeToolResult(message, showImages, args, theme) {
14759
14793
 
14760
14794
  // src/react-ink/components/ToolEventBlock.tsx
14761
14795
  import stripAnsi5 from "strip-ansi";
14762
- function statusMarker(status) {
14796
+ var STATUS_DOT = "\u25CF";
14797
+ var COLLAPSED_CONTENT_LINES = 2;
14798
+ var EXPANDED_CONTENT_LINES = 20;
14799
+ function contentConnector(isFirst) {
14800
+ return isFirst ? "\u2514 " : " ";
14801
+ }
14802
+ function statusColorKey(status) {
14763
14803
  switch (status) {
14764
14804
  case "error":
14765
- return "!";
14805
+ return "error";
14766
14806
  case "success":
14767
- return "=";
14807
+ return "success";
14768
14808
  default:
14769
- return ">";
14809
+ return "accent";
14770
14810
  }
14771
14811
  }
14772
- function statusColorKey(status) {
14773
- return status === "error" ? "error" : "text";
14774
- }
14775
14812
  function plainToolText(text) {
14776
14813
  return stripAnsi5(text);
14777
14814
  }
@@ -14807,7 +14844,8 @@ function ToolEventBlock({
14807
14844
  emptyText,
14808
14845
  indent = 0,
14809
14846
  marginBottom = 1,
14810
- maxContentLines = 10,
14847
+ maxContentLines = COLLAPSED_CONTENT_LINES,
14848
+ moreHint,
14811
14849
  preformatted = false,
14812
14850
  showSummaryInline = false,
14813
14851
  showTitle = true,
@@ -14827,21 +14865,22 @@ function ToolEventBlock({
14827
14865
  ...detailLines.map((text) => ({ kind: "detail", text }))
14828
14866
  ];
14829
14867
  const { visibleLines, hiddenLineCount } = clampContentLines(combinedLines, maxContentLines);
14868
+ const contentIndent = showTitle ? 2 : 0;
14830
14869
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom, marginLeft: indent, children: [
14831
14870
  showTitle ? /* @__PURE__ */ jsxs(Box, { children: [
14832
- /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), plainToolText(`${statusMarker(status)} `)) }),
14833
- /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), plainToolText(title)) }),
14871
+ /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), `${STATUS_DOT} `) }),
14872
+ /* @__PURE__ */ jsx(Text, { bold: true, children: theme.color("text", plainToolText(title)) }),
14834
14873
  showSummaryInline && normalizedSummary ? /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(` (${normalizedSummary})`)) }) : null
14835
14874
  ] }) : null,
14836
- visibleLines.map((line4, index) => /* @__PURE__ */ jsx(
14837
- Box,
14838
- {
14839
- marginLeft: line4.kind === "response" ? showTitle ? 2 : 0 : showTitle ? 4 : 2,
14840
- children: preformatted ? /* @__PURE__ */ jsx(Text, { children: line4.text }) : /* @__PURE__ */ jsx(Text, { children: theme.color("text", plainToolText(line4.text)) })
14841
- },
14842
- `${line4.kind}:${index}:${stripAnsi5(line4.text)}`
14843
- )),
14844
- hiddenLineCount > 0 ? /* @__PURE__ */ jsx(Box, { marginLeft: showTitle ? 4 : 2, children: /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(`... ${hiddenLineCount} more line(s)`)) }) }) : null
14875
+ visibleLines.map((line4, index) => /* @__PURE__ */ jsxs(Box, { marginLeft: contentIndent, children: [
14876
+ /* @__PURE__ */ jsx(Text, { children: theme.dim(contentConnector(index === 0)) }),
14877
+ preformatted ? /* @__PURE__ */ jsx(Text, { children: line4.text }) : /* @__PURE__ */ jsx(Text, { children: theme.color("text", plainToolText(line4.text)) })
14878
+ ] }, `${line4.kind}:${index}:${stripAnsi5(line4.text)}`)),
14879
+ hiddenLineCount > 0 ? /* @__PURE__ */ jsxs(Box, { marginLeft: contentIndent, children: [
14880
+ /* @__PURE__ */ jsx(Text, { children: theme.dim(contentConnector(visibleLines.length === 0)) }),
14881
+ /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(`\u2026 ${hiddenLineCount} more line(s)`)) }),
14882
+ moreHint ? /* @__PURE__ */ jsx(Text, { children: theme.dim(plainToolText(` \xB7 ${moreHint}`)) }) : null
14883
+ ] }) : null
14845
14884
  ] });
14846
14885
  }
14847
14886
 
@@ -14937,7 +14976,7 @@ function ToolResultBlock({ expanded = false, message, nested = false, showImages
14937
14976
  emptyText: descriptor.emptyText,
14938
14977
  indent,
14939
14978
  marginBottom: 0,
14940
- maxContentLines: 0,
14979
+ maxContentLines: 1,
14941
14980
  showSummaryInline: false,
14942
14981
  showTitle: !nested,
14943
14982
  status: message.isError ? "error" : "success",
@@ -14956,7 +14995,8 @@ function ToolResultBlock({ expanded = false, message, nested = false, showImages
14956
14995
  emptyText: descriptor.emptyText,
14957
14996
  indent,
14958
14997
  marginBottom: 0,
14959
- maxContentLines: expanded ? Number.MAX_SAFE_INTEGER : 10,
14998
+ maxContentLines: expanded ? EXPANDED_CONTENT_LINES : COLLAPSED_CONTENT_LINES,
14999
+ moreHint: expanded ? "ctrl+o to collapse" : "ctrl+o to expand",
14960
15000
  preformatted: descriptor.preformatted,
14961
15001
  showSummaryInline: false,
14962
15002
  showTitle: !nested,
@@ -15221,7 +15261,7 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
15221
15261
  return null;
15222
15262
  }
15223
15263
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, marginTop: 1, children: [
15224
- /* @__PURE__ */ jsx(Text, { children: theme.color("accent", `Tool Activity${recent.length > 0 ? ` ${recent.length}` : ""}`) }),
15264
+ recent.length > 0 ? /* @__PURE__ */ jsx(Text, { children: theme.color("accent", `Tool Activity ${recent.length}`) }) : null,
15225
15265
  recent.map((tool) => {
15226
15266
  const descriptor = describeToolExecution(tool);
15227
15267
  return /* @__PURE__ */ jsx(
@@ -15231,7 +15271,8 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
15231
15271
  emptyText: descriptor.emptyText,
15232
15272
  indent: 1,
15233
15273
  marginBottom: 0,
15234
- maxContentLines: expandToolOutputs ? Number.MAX_SAFE_INTEGER : 10,
15274
+ maxContentLines: expandToolOutputs ? EXPANDED_CONTENT_LINES : COLLAPSED_CONTENT_LINES,
15275
+ moreHint: expandToolOutputs ? "ctrl+o to collapse" : "ctrl+o to expand",
15235
15276
  showSummaryInline: true,
15236
15277
  status: tool.status,
15237
15278
  summary: descriptor.summary,
@@ -15247,7 +15288,7 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
15247
15288
  theme.muted(` ${message.mode === "steer" ? "Steering" : "Follow-up"}: `),
15248
15289
  message.text.length > 90 ? `${message.text.slice(0, 87)}...` : message.text
15249
15290
  ] }, message.id)),
15250
- /* @__PURE__ */ jsx(Text, { children: theme.muted(" Alt+Up restores queued messages to the prompt") })
15291
+ /* @__PURE__ */ jsx(Text, { children: theme.muted(" Ctrl+X runs the newest queued message now \xB7 Alt+Up restores it to the prompt") })
15251
15292
  ] }) : snapshot.pendingMessageCount > 0 ? /* @__PURE__ */ jsx(Text, { children: theme.muted(`${snapshot.pendingMessageCount} queued message(s) waiting for the next turn`) }) : null
15252
15293
  ] });
15253
15294
  }
@@ -36,6 +36,40 @@ var MODEL_CARDS = [
36
36
  cacheWritePerMTok: 18.75
37
37
  }
38
38
  },
39
+ {
40
+ id: "claude-opus-4-7",
41
+ provider: "anthropic",
42
+ api: "anthropic-messages",
43
+ displayName: "Claude Opus 4.7",
44
+ contextWindow: 1e6,
45
+ maxOutputTokens: 128e3,
46
+ modalities: ["text", "image"],
47
+ reasoning: true,
48
+ cost: {
49
+ // approximate — flagship tier
50
+ inputPerMTok: 5,
51
+ outputPerMTok: 25,
52
+ cacheReadPerMTok: 0.5,
53
+ cacheWritePerMTok: 6.25
54
+ }
55
+ },
56
+ {
57
+ id: "claude-opus-4-8",
58
+ provider: "anthropic",
59
+ api: "anthropic-messages",
60
+ displayName: "Claude Opus 4.8",
61
+ contextWindow: 1e6,
62
+ maxOutputTokens: 128e3,
63
+ modalities: ["text", "image"],
64
+ reasoning: true,
65
+ cost: {
66
+ // approximate — flagship tier
67
+ inputPerMTok: 5,
68
+ outputPerMTok: 25,
69
+ cacheReadPerMTok: 0.5,
70
+ cacheWritePerMTok: 6.25
71
+ }
72
+ },
39
73
  {
40
74
  id: "claude-sonnet-4",
41
75
  provider: "anthropic",
package/dist/react-ink.js CHANGED
@@ -2051,19 +2051,22 @@ function describeToolResult(message, showImages, args, theme) {
2051
2051
 
2052
2052
  // src/react-ink/components/ToolEventBlock.tsx
2053
2053
  import stripAnsi5 from "strip-ansi";
2054
- function statusMarker(status) {
2054
+ var STATUS_DOT = "\u25CF";
2055
+ var COLLAPSED_CONTENT_LINES = 2;
2056
+ var EXPANDED_CONTENT_LINES = 20;
2057
+ function contentConnector(isFirst) {
2058
+ return isFirst ? "\u2514 " : " ";
2059
+ }
2060
+ function statusColorKey(status) {
2055
2061
  switch (status) {
2056
2062
  case "error":
2057
- return "!";
2063
+ return "error";
2058
2064
  case "success":
2059
- return "=";
2065
+ return "success";
2060
2066
  default:
2061
- return ">";
2067
+ return "accent";
2062
2068
  }
2063
2069
  }
2064
- function statusColorKey(status) {
2065
- return status === "error" ? "error" : "text";
2066
- }
2067
2070
  function plainToolText(text) {
2068
2071
  return stripAnsi5(text);
2069
2072
  }
@@ -2099,7 +2102,8 @@ function ToolEventBlock({
2099
2102
  emptyText,
2100
2103
  indent = 0,
2101
2104
  marginBottom = 1,
2102
- maxContentLines = 10,
2105
+ maxContentLines = COLLAPSED_CONTENT_LINES,
2106
+ moreHint,
2103
2107
  preformatted = false,
2104
2108
  showSummaryInline = false,
2105
2109
  showTitle = true,
@@ -2119,21 +2123,22 @@ function ToolEventBlock({
2119
2123
  ...detailLines.map((text) => ({ kind: "detail", text }))
2120
2124
  ];
2121
2125
  const { visibleLines, hiddenLineCount } = clampContentLines(combinedLines, maxContentLines);
2126
+ const contentIndent = showTitle ? 2 : 0;
2122
2127
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom, marginLeft: indent, children: [
2123
2128
  showTitle ? /* @__PURE__ */ jsxs(Box, { children: [
2124
- /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), plainToolText(`${statusMarker(status)} `)) }),
2125
- /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), plainToolText(title)) }),
2129
+ /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), `${STATUS_DOT} `) }),
2130
+ /* @__PURE__ */ jsx(Text, { bold: true, children: theme.color("text", plainToolText(title)) }),
2126
2131
  showSummaryInline && normalizedSummary ? /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(` (${normalizedSummary})`)) }) : null
2127
2132
  ] }) : null,
2128
- visibleLines.map((line, index) => /* @__PURE__ */ jsx(
2129
- Box,
2130
- {
2131
- marginLeft: line.kind === "response" ? showTitle ? 2 : 0 : showTitle ? 4 : 2,
2132
- children: preformatted ? /* @__PURE__ */ jsx(Text, { children: line.text }) : /* @__PURE__ */ jsx(Text, { children: theme.color("text", plainToolText(line.text)) })
2133
- },
2134
- `${line.kind}:${index}:${stripAnsi5(line.text)}`
2135
- )),
2136
- hiddenLineCount > 0 ? /* @__PURE__ */ jsx(Box, { marginLeft: showTitle ? 4 : 2, children: /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(`... ${hiddenLineCount} more line(s)`)) }) }) : null
2133
+ visibleLines.map((line, index) => /* @__PURE__ */ jsxs(Box, { marginLeft: contentIndent, children: [
2134
+ /* @__PURE__ */ jsx(Text, { children: theme.dim(contentConnector(index === 0)) }),
2135
+ preformatted ? /* @__PURE__ */ jsx(Text, { children: line.text }) : /* @__PURE__ */ jsx(Text, { children: theme.color("text", plainToolText(line.text)) })
2136
+ ] }, `${line.kind}:${index}:${stripAnsi5(line.text)}`)),
2137
+ hiddenLineCount > 0 ? /* @__PURE__ */ jsxs(Box, { marginLeft: contentIndent, children: [
2138
+ /* @__PURE__ */ jsx(Text, { children: theme.dim(contentConnector(visibleLines.length === 0)) }),
2139
+ /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(`\u2026 ${hiddenLineCount} more line(s)`)) }),
2140
+ moreHint ? /* @__PURE__ */ jsx(Text, { children: theme.dim(plainToolText(` \xB7 ${moreHint}`)) }) : null
2141
+ ] }) : null
2137
2142
  ] });
2138
2143
  }
2139
2144
 
@@ -2229,7 +2234,7 @@ function ToolResultBlock({ expanded = false, message, nested = false, showImages
2229
2234
  emptyText: descriptor.emptyText,
2230
2235
  indent,
2231
2236
  marginBottom: 0,
2232
- maxContentLines: 0,
2237
+ maxContentLines: 1,
2233
2238
  showSummaryInline: false,
2234
2239
  showTitle: !nested,
2235
2240
  status: message.isError ? "error" : "success",
@@ -2248,7 +2253,8 @@ function ToolResultBlock({ expanded = false, message, nested = false, showImages
2248
2253
  emptyText: descriptor.emptyText,
2249
2254
  indent,
2250
2255
  marginBottom: 0,
2251
- maxContentLines: expanded ? Number.MAX_SAFE_INTEGER : 10,
2256
+ maxContentLines: expanded ? EXPANDED_CONTENT_LINES : COLLAPSED_CONTENT_LINES,
2257
+ moreHint: expanded ? "ctrl+o to collapse" : "ctrl+o to expand",
2252
2258
  preformatted: descriptor.preformatted,
2253
2259
  showSummaryInline: false,
2254
2260
  showTitle: !nested,
@@ -2513,7 +2519,7 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
2513
2519
  return null;
2514
2520
  }
2515
2521
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, marginTop: 1, children: [
2516
- /* @__PURE__ */ jsx(Text, { children: theme.color("accent", `Tool Activity${recent.length > 0 ? ` ${recent.length}` : ""}`) }),
2522
+ recent.length > 0 ? /* @__PURE__ */ jsx(Text, { children: theme.color("accent", `Tool Activity ${recent.length}`) }) : null,
2517
2523
  recent.map((tool) => {
2518
2524
  const descriptor = describeToolExecution(tool);
2519
2525
  return /* @__PURE__ */ jsx(
@@ -2523,7 +2529,8 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
2523
2529
  emptyText: descriptor.emptyText,
2524
2530
  indent: 1,
2525
2531
  marginBottom: 0,
2526
- maxContentLines: expandToolOutputs ? Number.MAX_SAFE_INTEGER : 10,
2532
+ maxContentLines: expandToolOutputs ? EXPANDED_CONTENT_LINES : COLLAPSED_CONTENT_LINES,
2533
+ moreHint: expandToolOutputs ? "ctrl+o to collapse" : "ctrl+o to expand",
2527
2534
  showSummaryInline: true,
2528
2535
  status: tool.status,
2529
2536
  summary: descriptor.summary,
@@ -2539,7 +2546,7 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
2539
2546
  theme.muted(` ${message.mode === "steer" ? "Steering" : "Follow-up"}: `),
2540
2547
  message.text.length > 90 ? `${message.text.slice(0, 87)}...` : message.text
2541
2548
  ] }, message.id)),
2542
- /* @__PURE__ */ jsx(Text, { children: theme.muted(" Alt+Up restores queued messages to the prompt") })
2549
+ /* @__PURE__ */ jsx(Text, { children: theme.muted(" Ctrl+X runs the newest queued message now \xB7 Alt+Up restores it to the prompt") })
2543
2550
  ] }) : snapshot.pendingMessageCount > 0 ? /* @__PURE__ */ jsx(Text, { children: theme.muted(`${snapshot.pendingMessageCount} queued message(s) waiting for the next turn`) }) : null
2544
2551
  ] });
2545
2552
  }
@@ -3759,6 +3766,7 @@ export {
3759
3766
  BashMessageView,
3760
3767
  BranchSummaryMessageView,
3761
3768
  CHANGE_THRESHOLD,
3769
+ COLLAPSED_CONTENT_LINES,
3762
3770
  CONTEXT_LINES,
3763
3771
  ChangelogBlock,
3764
3772
  CompactionMessageView,
@@ -3766,6 +3774,7 @@ export {
3766
3774
  DialogFrame,
3767
3775
  Diff,
3768
3776
  DisplayBlockView,
3777
+ EXPANDED_CONTENT_LINES,
3769
3778
  Footer,
3770
3779
  LoginDialog,
3771
3780
  Markdown,
package/dist/runtime.js CHANGED
@@ -36,6 +36,40 @@ var MODEL_CARDS = [
36
36
  cacheWritePerMTok: 18.75
37
37
  }
38
38
  },
39
+ {
40
+ id: "claude-opus-4-7",
41
+ provider: "anthropic",
42
+ api: "anthropic-messages",
43
+ displayName: "Claude Opus 4.7",
44
+ contextWindow: 1e6,
45
+ maxOutputTokens: 128e3,
46
+ modalities: ["text", "image"],
47
+ reasoning: true,
48
+ cost: {
49
+ // approximate — flagship tier
50
+ inputPerMTok: 5,
51
+ outputPerMTok: 25,
52
+ cacheReadPerMTok: 0.5,
53
+ cacheWritePerMTok: 6.25
54
+ }
55
+ },
56
+ {
57
+ id: "claude-opus-4-8",
58
+ provider: "anthropic",
59
+ api: "anthropic-messages",
60
+ displayName: "Claude Opus 4.8",
61
+ contextWindow: 1e6,
62
+ maxOutputTokens: 128e3,
63
+ modalities: ["text", "image"],
64
+ reasoning: true,
65
+ cost: {
66
+ // approximate — flagship tier
67
+ inputPerMTok: 5,
68
+ outputPerMTok: 25,
69
+ cacheReadPerMTok: 0.5,
70
+ cacheWritePerMTok: 6.25
71
+ }
72
+ },
39
73
  {
40
74
  id: "claude-sonnet-4",
41
75
  provider: "anthropic",
package/dist/shell-app.js CHANGED
@@ -275,6 +275,40 @@ var MODEL_CARDS = [
275
275
  cacheWritePerMTok: 18.75
276
276
  }
277
277
  },
278
+ {
279
+ id: "claude-opus-4-7",
280
+ provider: "anthropic",
281
+ api: "anthropic-messages",
282
+ displayName: "Claude Opus 4.7",
283
+ contextWindow: 1e6,
284
+ maxOutputTokens: 128e3,
285
+ modalities: ["text", "image"],
286
+ reasoning: true,
287
+ cost: {
288
+ // approximate — flagship tier
289
+ inputPerMTok: 5,
290
+ outputPerMTok: 25,
291
+ cacheReadPerMTok: 0.5,
292
+ cacheWritePerMTok: 6.25
293
+ }
294
+ },
295
+ {
296
+ id: "claude-opus-4-8",
297
+ provider: "anthropic",
298
+ api: "anthropic-messages",
299
+ displayName: "Claude Opus 4.8",
300
+ contextWindow: 1e6,
301
+ maxOutputTokens: 128e3,
302
+ modalities: ["text", "image"],
303
+ reasoning: true,
304
+ cost: {
305
+ // approximate — flagship tier
306
+ inputPerMTok: 5,
307
+ outputPerMTok: 25,
308
+ cacheReadPerMTok: 0.5,
309
+ cacheWritePerMTok: 6.25
310
+ }
311
+ },
278
312
  {
279
313
  id: "claude-sonnet-4",
280
314
  provider: "anthropic",
@@ -10438,19 +10472,22 @@ function describeToolResult(message, showImages, args, theme) {
10438
10472
 
10439
10473
  // src/react-ink/components/ToolEventBlock.tsx
10440
10474
  import stripAnsi5 from "strip-ansi";
10441
- function statusMarker(status) {
10475
+ var STATUS_DOT = "\u25CF";
10476
+ var COLLAPSED_CONTENT_LINES = 2;
10477
+ var EXPANDED_CONTENT_LINES = 20;
10478
+ function contentConnector(isFirst) {
10479
+ return isFirst ? "\u2514 " : " ";
10480
+ }
10481
+ function statusColorKey(status) {
10442
10482
  switch (status) {
10443
10483
  case "error":
10444
- return "!";
10484
+ return "error";
10445
10485
  case "success":
10446
- return "=";
10486
+ return "success";
10447
10487
  default:
10448
- return ">";
10488
+ return "accent";
10449
10489
  }
10450
10490
  }
10451
- function statusColorKey(status) {
10452
- return status === "error" ? "error" : "text";
10453
- }
10454
10491
  function plainToolText(text) {
10455
10492
  return stripAnsi5(text);
10456
10493
  }
@@ -10486,7 +10523,8 @@ function ToolEventBlock({
10486
10523
  emptyText,
10487
10524
  indent = 0,
10488
10525
  marginBottom = 1,
10489
- maxContentLines = 10,
10526
+ maxContentLines = COLLAPSED_CONTENT_LINES,
10527
+ moreHint,
10490
10528
  preformatted = false,
10491
10529
  showSummaryInline = false,
10492
10530
  showTitle = true,
@@ -10506,21 +10544,22 @@ function ToolEventBlock({
10506
10544
  ...detailLines.map((text) => ({ kind: "detail", text }))
10507
10545
  ];
10508
10546
  const { visibleLines, hiddenLineCount } = clampContentLines(combinedLines, maxContentLines);
10547
+ const contentIndent = showTitle ? 2 : 0;
10509
10548
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom, marginLeft: indent, children: [
10510
10549
  showTitle ? /* @__PURE__ */ jsxs(Box, { children: [
10511
- /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), plainToolText(`${statusMarker(status)} `)) }),
10512
- /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), plainToolText(title)) }),
10550
+ /* @__PURE__ */ jsx(Text, { children: theme.color(statusColorKey(status), `${STATUS_DOT} `) }),
10551
+ /* @__PURE__ */ jsx(Text, { bold: true, children: theme.color("text", plainToolText(title)) }),
10513
10552
  showSummaryInline && normalizedSummary ? /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(` (${normalizedSummary})`)) }) : null
10514
10553
  ] }) : null,
10515
- visibleLines.map((line, index) => /* @__PURE__ */ jsx(
10516
- Box,
10517
- {
10518
- marginLeft: line.kind === "response" ? showTitle ? 2 : 0 : showTitle ? 4 : 2,
10519
- children: preformatted ? /* @__PURE__ */ jsx(Text, { children: line.text }) : /* @__PURE__ */ jsx(Text, { children: theme.color("text", plainToolText(line.text)) })
10520
- },
10521
- `${line.kind}:${index}:${stripAnsi5(line.text)}`
10522
- )),
10523
- hiddenLineCount > 0 ? /* @__PURE__ */ jsx(Box, { marginLeft: showTitle ? 4 : 2, children: /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(`... ${hiddenLineCount} more line(s)`)) }) }) : null
10554
+ visibleLines.map((line, index) => /* @__PURE__ */ jsxs(Box, { marginLeft: contentIndent, children: [
10555
+ /* @__PURE__ */ jsx(Text, { children: theme.dim(contentConnector(index === 0)) }),
10556
+ preformatted ? /* @__PURE__ */ jsx(Text, { children: line.text }) : /* @__PURE__ */ jsx(Text, { children: theme.color("text", plainToolText(line.text)) })
10557
+ ] }, `${line.kind}:${index}:${stripAnsi5(line.text)}`)),
10558
+ hiddenLineCount > 0 ? /* @__PURE__ */ jsxs(Box, { marginLeft: contentIndent, children: [
10559
+ /* @__PURE__ */ jsx(Text, { children: theme.dim(contentConnector(visibleLines.length === 0)) }),
10560
+ /* @__PURE__ */ jsx(Text, { children: theme.muted(plainToolText(`\u2026 ${hiddenLineCount} more line(s)`)) }),
10561
+ moreHint ? /* @__PURE__ */ jsx(Text, { children: theme.dim(plainToolText(` \xB7 ${moreHint}`)) }) : null
10562
+ ] }) : null
10524
10563
  ] });
10525
10564
  }
10526
10565
 
@@ -10616,7 +10655,7 @@ function ToolResultBlock({ expanded = false, message, nested = false, showImages
10616
10655
  emptyText: descriptor.emptyText,
10617
10656
  indent,
10618
10657
  marginBottom: 0,
10619
- maxContentLines: 0,
10658
+ maxContentLines: 1,
10620
10659
  showSummaryInline: false,
10621
10660
  showTitle: !nested,
10622
10661
  status: message.isError ? "error" : "success",
@@ -10635,7 +10674,8 @@ function ToolResultBlock({ expanded = false, message, nested = false, showImages
10635
10674
  emptyText: descriptor.emptyText,
10636
10675
  indent,
10637
10676
  marginBottom: 0,
10638
- maxContentLines: expanded ? Number.MAX_SAFE_INTEGER : 10,
10677
+ maxContentLines: expanded ? EXPANDED_CONTENT_LINES : COLLAPSED_CONTENT_LINES,
10678
+ moreHint: expanded ? "ctrl+o to collapse" : "ctrl+o to expand",
10639
10679
  preformatted: descriptor.preformatted,
10640
10680
  showSummaryInline: false,
10641
10681
  showTitle: !nested,
@@ -10900,7 +10940,7 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
10900
10940
  return null;
10901
10941
  }
10902
10942
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, marginTop: 1, children: [
10903
- /* @__PURE__ */ jsx(Text, { children: theme.color("accent", `Tool Activity${recent.length > 0 ? ` ${recent.length}` : ""}`) }),
10943
+ recent.length > 0 ? /* @__PURE__ */ jsx(Text, { children: theme.color("accent", `Tool Activity ${recent.length}`) }) : null,
10904
10944
  recent.map((tool) => {
10905
10945
  const descriptor = describeToolExecution(tool);
10906
10946
  return /* @__PURE__ */ jsx(
@@ -10910,7 +10950,8 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
10910
10950
  emptyText: descriptor.emptyText,
10911
10951
  indent: 1,
10912
10952
  marginBottom: 0,
10913
- maxContentLines: expandToolOutputs ? Number.MAX_SAFE_INTEGER : 10,
10953
+ maxContentLines: expandToolOutputs ? EXPANDED_CONTENT_LINES : COLLAPSED_CONTENT_LINES,
10954
+ moreHint: expandToolOutputs ? "ctrl+o to collapse" : "ctrl+o to expand",
10914
10955
  showSummaryInline: true,
10915
10956
  status: tool.status,
10916
10957
  summary: descriptor.summary,
@@ -10926,7 +10967,7 @@ function TaskPanel({ expandToolOutputs = false, pendingMessages = [], snapshot,
10926
10967
  theme.muted(` ${message.mode === "steer" ? "Steering" : "Follow-up"}: `),
10927
10968
  message.text.length > 90 ? `${message.text.slice(0, 87)}...` : message.text
10928
10969
  ] }, message.id)),
10929
- /* @__PURE__ */ jsx(Text, { children: theme.muted(" Alt+Up restores queued messages to the prompt") })
10970
+ /* @__PURE__ */ jsx(Text, { children: theme.muted(" Ctrl+X runs the newest queued message now \xB7 Alt+Up restores it to the prompt") })
10930
10971
  ] }) : snapshot.pendingMessageCount > 0 ? /* @__PURE__ */ jsx(Text, { children: theme.muted(`${snapshot.pendingMessageCount} queued message(s) waiting for the next turn`) }) : null
10931
10972
  ] });
10932
10973
  }
package/dist/smithy.js CHANGED
@@ -3475,6 +3475,40 @@ var MODEL_CARDS = [
3475
3475
  cacheWritePerMTok: 18.75
3476
3476
  }
3477
3477
  },
3478
+ {
3479
+ id: "claude-opus-4-7",
3480
+ provider: "anthropic",
3481
+ api: "anthropic-messages",
3482
+ displayName: "Claude Opus 4.7",
3483
+ contextWindow: 1e6,
3484
+ maxOutputTokens: 128e3,
3485
+ modalities: ["text", "image"],
3486
+ reasoning: true,
3487
+ cost: {
3488
+ // approximate — flagship tier
3489
+ inputPerMTok: 5,
3490
+ outputPerMTok: 25,
3491
+ cacheReadPerMTok: 0.5,
3492
+ cacheWritePerMTok: 6.25
3493
+ }
3494
+ },
3495
+ {
3496
+ id: "claude-opus-4-8",
3497
+ provider: "anthropic",
3498
+ api: "anthropic-messages",
3499
+ displayName: "Claude Opus 4.8",
3500
+ contextWindow: 1e6,
3501
+ maxOutputTokens: 128e3,
3502
+ modalities: ["text", "image"],
3503
+ reasoning: true,
3504
+ cost: {
3505
+ // approximate — flagship tier
3506
+ inputPerMTok: 5,
3507
+ outputPerMTok: 25,
3508
+ cacheReadPerMTok: 0.5,
3509
+ cacheWritePerMTok: 6.25
3510
+ }
3511
+ },
3478
3512
  {
3479
3513
  id: "claude-sonnet-4",
3480
3514
  provider: "anthropic",
package/dist/swarm.js CHANGED
@@ -39,6 +39,40 @@ var MODEL_CARDS = [
39
39
  cacheWritePerMTok: 18.75
40
40
  }
41
41
  },
42
+ {
43
+ id: "claude-opus-4-7",
44
+ provider: "anthropic",
45
+ api: "anthropic-messages",
46
+ displayName: "Claude Opus 4.7",
47
+ contextWindow: 1e6,
48
+ maxOutputTokens: 128e3,
49
+ modalities: ["text", "image"],
50
+ reasoning: true,
51
+ cost: {
52
+ // approximate — flagship tier
53
+ inputPerMTok: 5,
54
+ outputPerMTok: 25,
55
+ cacheReadPerMTok: 0.5,
56
+ cacheWritePerMTok: 6.25
57
+ }
58
+ },
59
+ {
60
+ id: "claude-opus-4-8",
61
+ provider: "anthropic",
62
+ api: "anthropic-messages",
63
+ displayName: "Claude Opus 4.8",
64
+ contextWindow: 1e6,
65
+ maxOutputTokens: 128e3,
66
+ modalities: ["text", "image"],
67
+ reasoning: true,
68
+ cost: {
69
+ // approximate — flagship tier
70
+ inputPerMTok: 5,
71
+ outputPerMTok: 25,
72
+ cacheReadPerMTok: 0.5,
73
+ cacheWritePerMTok: 6.25
74
+ }
75
+ },
42
76
  {
43
77
  id: "claude-sonnet-4",
44
78
  provider: "anthropic",
@@ -1279,6 +1279,40 @@ export declare const MODELS: {
1279
1279
  contextWindow: number;
1280
1280
  maxTokens: number;
1281
1281
  };
1282
+ readonly "claude-opus-4-7": {
1283
+ id: string;
1284
+ name: string;
1285
+ api: "anthropic-messages";
1286
+ provider: string;
1287
+ baseUrl: string;
1288
+ reasoning: true;
1289
+ input: ("text" | "image")[];
1290
+ cost: {
1291
+ input: number;
1292
+ output: number;
1293
+ cacheRead: number;
1294
+ cacheWrite: number;
1295
+ };
1296
+ contextWindow: number;
1297
+ maxTokens: number;
1298
+ };
1299
+ readonly "claude-opus-4-8": {
1300
+ id: string;
1301
+ name: string;
1302
+ api: "anthropic-messages";
1303
+ provider: string;
1304
+ baseUrl: string;
1305
+ reasoning: true;
1306
+ input: ("text" | "image")[];
1307
+ cost: {
1308
+ input: number;
1309
+ output: number;
1310
+ cacheRead: number;
1311
+ cacheWrite: number;
1312
+ };
1313
+ contextWindow: number;
1314
+ maxTokens: number;
1315
+ };
1282
1316
  readonly "claude-sonnet-4-0": {
1283
1317
  id: string;
1284
1318
  name: string;
@@ -12,6 +12,12 @@ interface ToolEventBlockProps {
12
12
  showTitle?: boolean;
13
13
  showSummaryInline?: boolean;
14
14
  maxContentLines?: number;
15
+ /**
16
+ * Appended to the "… N more line(s)" overflow marker (e.g. "ctrl+o to
17
+ * expand"), so the user can discover how to reveal the folded output. Omitted
18
+ * → the bare count is shown.
19
+ */
20
+ moreHint?: string;
15
21
  /**
16
22
  * When true the detail body already carries syntax-highlight ANSI; render it
17
23
  * verbatim instead of stripping the escapes. stripAnsi is still used for the
@@ -20,6 +26,23 @@ interface ToolEventBlockProps {
20
26
  */
21
27
  preformatted?: boolean;
22
28
  }
29
+ /**
30
+ * How many content lines a collapsed tool event shows before the rest is folded
31
+ * behind a "… N more line(s)" affordance. Kept deliberately small so a tool reads
32
+ * as a tight two-to-three-line block (the ● action header plus a summary line),
33
+ * not a multi-line output dump; expanding a tool lifts this cap. Callers that
34
+ * render tool bodies (ToolResultBlock, TaskPanel) share this so the collapsed
35
+ * height is consistent everywhere.
36
+ */
37
+ export declare const COLLAPSED_CONTENT_LINES = 2;
38
+ /**
39
+ * How many content lines an *expanded* tool event shows (Ctrl+O). A bounded
40
+ * reveal — enough to actually read what a tool read/wrote/ran (10–20 lines)
41
+ * without flooding the transcript with a whole file; anything past it stays
42
+ * folded behind the "… N more" marker. Toggling Ctrl+O again collapses back to
43
+ * {@link COLLAPSED_CONTENT_LINES}.
44
+ */
45
+ export declare const EXPANDED_CONTENT_LINES = 20;
23
46
  export declare function statusColorKey(status: ToolEventStatus): string;
24
- export declare function ToolEventBlock({ detail, emptyText, indent, marginBottom, maxContentLines, preformatted, showSummaryInline, showTitle, status, summary, theme, title, }: ToolEventBlockProps): JSX.Element;
47
+ export declare function ToolEventBlock({ detail, emptyText, indent, marginBottom, maxContentLines, moreHint, preformatted, showSummaryInline, showTitle, status, summary, theme, title, }: ToolEventBlockProps): JSX.Element;
25
48
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "indusagi",
3
- "version": "0.13.1",
3
+ "version": "0.13.3",
4
4
  "description": "Indusagi — a terminal-first AI coding agent framework. Clean-room implementation.",
5
5
  "author": "Varun Israni",
6
6
  "license": "MIT",