4runr-os 2.10.62 → 2.10.63

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.
@@ -256,11 +256,11 @@ impl SentinelConfigState {
256
256
  }
257
257
  }
258
258
  CustomField::MaxCost => {
259
- let step = 0.25;
259
+ let step = 0.05;
260
260
  if increase {
261
- d.max_cost = (d.max_cost + step).min(100.0);
261
+ d.max_cost = round_cost((d.max_cost + step).min(100.0));
262
262
  } else {
263
- d.max_cost = (d.max_cost - step).max(0.01);
263
+ d.max_cost = round_cost((d.max_cost - step).max(0.05));
264
264
  }
265
265
  }
266
266
  CustomField::LoopWindow => {
@@ -430,10 +430,28 @@ pub fn parse_health(v: &Value) -> SentinelHealthSnapshot {
430
430
  }
431
431
 
432
432
  fn fmt_ms(ms: u64) -> String {
433
- if ms >= 60_000 {
434
- format!("{:.0}m", ms as f64 / 60_000.0)
433
+ let total_secs = ms / 1000;
434
+ let mins = total_secs / 60;
435
+ let secs = total_secs % 60;
436
+ if mins > 0 {
437
+ format!("{}:{:02}", mins, secs)
435
438
  } else {
436
- format!("{:.0}s", ms as f64 / 1000.0)
439
+ format!("{}s", secs)
440
+ }
441
+ }
442
+
443
+ fn round_cost(usd: f64) -> f64 {
444
+ (usd * 100.0).round() / 100.0
445
+ }
446
+
447
+ fn fmt_cost(usd: f64) -> String {
448
+ let cents = (round_cost(usd) * 100.0).round() as i64;
449
+ let dollars = cents / 100;
450
+ let rem = cents.abs() % 100;
451
+ if rem == 0 {
452
+ format!("${}", dollars)
453
+ } else {
454
+ format!("${}.{:02}", dollars, rem)
437
455
  }
438
456
  }
439
457
 
@@ -449,7 +467,7 @@ fn custom_field_value(d: &SentinelCurrentConfig, field: CustomField) -> String {
449
467
  CustomField::IdleMs => fmt_ms(d.idle_ms),
450
468
  CustomField::MaxDurationMs => fmt_ms(d.duration_ms),
451
469
  CustomField::MaxTokens => format!("{}", d.max_tokens),
452
- CustomField::MaxCost => format!("${:.2}", d.max_cost),
470
+ CustomField::MaxCost => fmt_cost(d.max_cost),
453
471
  CustomField::LoopWindow => format!("{}s", d.loop_window),
454
472
  CustomField::LoopMax => format!("{}", d.loop_max),
455
473
  }
@@ -599,10 +617,7 @@ fn render_active_panel(f: &mut Frame, area: Rect, sc: &SentinelConfigState) {
599
617
  ]),
600
618
  Line::from(vec![
601
619
  Span::styled("Max cost: ", Style::default().fg(TEXT_DIM)),
602
- Span::styled(
603
- format!("${:.2}", sc.current_max_cost),
604
- Style::default().fg(AMBER_WARN),
605
- ),
620
+ Span::styled(fmt_cost(sc.current_max_cost), Style::default().fg(AMBER_WARN)),
606
621
  ]),
607
622
  Line::from(vec![
608
623
  Span::styled("Loop detect: ", Style::default().fg(TEXT_DIM)),
@@ -745,3 +760,25 @@ fn render_custom_help(f: &mut Frame, area: Rect, sc: &SentinelConfigState) {
745
760
 
746
761
  f.render_widget(Paragraph::new(lines).wrap(Wrap { trim: false }), inner);
747
762
  }
763
+
764
+ #[cfg(test)]
765
+ mod format_tests {
766
+ use super::{fmt_cost, fmt_ms};
767
+
768
+ #[test]
769
+ fn fmt_ms_shows_minutes_and_seconds() {
770
+ assert_eq!(fmt_ms(30_000), "30s");
771
+ assert_eq!(fmt_ms(60_000), "1:00");
772
+ assert_eq!(fmt_ms(75_000), "1:15");
773
+ assert_eq!(fmt_ms(240_000), "4:00");
774
+ assert_eq!(fmt_ms(255_000), "4:15");
775
+ }
776
+
777
+ #[test]
778
+ fn fmt_cost_shows_cents_when_present() {
779
+ assert_eq!(fmt_cost(1.0), "$1");
780
+ assert_eq!(fmt_cost(1.05), "$1.05");
781
+ assert_eq!(fmt_cost(1.15), "$1.15");
782
+ assert_eq!(fmt_cost(1.25), "$1.25");
783
+ }
784
+ }
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "4runr-os",
3
- "version": "2.10.62",
3
+ "version": "2.10.63",
4
4
  "type": "module",
5
- "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.10.62: Sentinel Custom tab edit limits with arrow keys, +/-, and mouse wheel.",
5
+ "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.10.63: Sentinel Custom — M:SS time display, cent-level cost steps.",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "4runr": "dist/index.js",