1 Commits

Author SHA1 Message Date
dependabot[bot]
a2454e1026 build(deps-dev): bump the minor-and-patch group across 1 directory with 2 updates
Bumps the minor-and-patch group with 2 updates in the / directory: @opencode-ai/plugin and [globals](https://github.com/sindresorhus/globals).


Updates `@opencode-ai/plugin` from 1.3.15 to 1.4.3

Updates `globals` from 17.4.0 to 17.5.0
- [Release notes](https://github.com/sindresorhus/globals/releases)
- [Commits](https://github.com/sindresorhus/globals/compare/v17.4.0...v17.5.0)

---
updated-dependencies:
- dependency-name: "@opencode-ai/plugin"
  dependency-version: 1.4.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: globals
  dependency-version: 17.5.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-19 04:53:41 +00:00
4 changed files with 635 additions and 1264 deletions

View File

@@ -411,27 +411,6 @@ pub struct SessionMetrics {
pub cost_usd: f64, pub cost_usd: f64,
} }
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct SessionBoardMeta {
pub lane: String,
pub project: Option<String>,
pub feature: Option<String>,
pub issue: Option<String>,
pub row_label: Option<String>,
pub previous_lane: Option<String>,
pub previous_row_label: Option<String>,
pub column_index: i64,
pub row_index: i64,
pub stack_index: i64,
pub progress_percent: i64,
pub status_detail: Option<String>,
pub movement_note: Option<String>,
pub activity_kind: Option<String>,
pub activity_note: Option<String>,
pub handoff_backlog: i64,
pub conflict_signal: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SessionMessage { pub struct SessionMessage {
pub id: i64, pub id: i64,

View File

@@ -19,8 +19,8 @@ use super::{
ContextGraphObservation, ContextGraphRecallEntry, ContextGraphRelation, ContextGraphSyncStats, ContextGraphObservation, ContextGraphRecallEntry, ContextGraphRelation, ContextGraphSyncStats,
ContextObservationPriority, DecisionLogEntry, FileActivityAction, FileActivityEntry, ContextObservationPriority, DecisionLogEntry, FileActivityAction, FileActivityEntry,
HarnessKind, RemoteDispatchKind, RemoteDispatchRequest, RemoteDispatchStatus, ScheduledTask, HarnessKind, RemoteDispatchKind, RemoteDispatchRequest, RemoteDispatchStatus, ScheduledTask,
Session, SessionAgentProfile, SessionBoardMeta, SessionHarnessInfo, SessionMessage, Session, SessionAgentProfile, SessionHarnessInfo, SessionMessage, SessionMetrics, SessionState,
SessionMetrics, SessionState, WorktreeInfo, WorktreeInfo,
}; };
pub struct StateStore { pub struct StateStore {
@@ -241,28 +241,6 @@ impl StateStore {
timestamp TEXT NOT NULL timestamp TEXT NOT NULL
); );
CREATE TABLE IF NOT EXISTS session_board (
session_id TEXT PRIMARY KEY REFERENCES sessions(id) ON DELETE CASCADE,
lane TEXT NOT NULL,
project TEXT,
feature TEXT,
issue TEXT,
row_label TEXT,
previous_lane TEXT,
previous_row_label TEXT,
column_index INTEGER NOT NULL DEFAULT 0,
row_index INTEGER NOT NULL DEFAULT 0,
stack_index INTEGER NOT NULL DEFAULT 0,
progress_percent INTEGER NOT NULL DEFAULT 0,
status_detail TEXT,
movement_note TEXT,
activity_kind TEXT,
activity_note TEXT,
handoff_backlog INTEGER NOT NULL DEFAULT 0,
conflict_signal TEXT,
updated_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS decision_log ( CREATE TABLE IF NOT EXISTS decision_log (
id INTEGER PRIMARY KEY AUTOINCREMENT, id INTEGER PRIMARY KEY AUTOINCREMENT,
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE, session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
@@ -408,9 +386,6 @@ impl StateStore {
CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_session, read); CREATE INDEX IF NOT EXISTS idx_messages_to ON messages(to_session, read);
CREATE INDEX IF NOT EXISTS idx_session_output_session CREATE INDEX IF NOT EXISTS idx_session_output_session
ON session_output(session_id, id); ON session_output(session_id, id);
CREATE INDEX IF NOT EXISTS idx_session_board_lane ON session_board(lane);
CREATE INDEX IF NOT EXISTS idx_session_board_coords
ON session_board(column_index, row_index, stack_index);
CREATE INDEX IF NOT EXISTS idx_decision_log_session CREATE INDEX IF NOT EXISTS idx_decision_log_session
ON decision_log(session_id, timestamp, id); ON decision_log(session_id, timestamp, id);
CREATE INDEX IF NOT EXISTS idx_context_graph_entities_session CREATE INDEX IF NOT EXISTS idx_context_graph_entities_session
@@ -434,8 +409,6 @@ impl StateStore {
", ",
)?; )?;
self.ensure_session_columns()?; self.ensure_session_columns()?;
self.ensure_session_board_columns()?;
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -509,51 +482,6 @@ impl StateStore {
.context("Failed to add output_tokens column to sessions table")?; .context("Failed to add output_tokens column to sessions table")?;
} }
if !self.has_column("sessions", "tokens_used")? {
self.conn
.execute(
"ALTER TABLE sessions ADD COLUMN tokens_used INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add tokens_used column to sessions table")?;
}
if !self.has_column("sessions", "tool_calls")? {
self.conn
.execute(
"ALTER TABLE sessions ADD COLUMN tool_calls INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add tool_calls column to sessions table")?;
}
if !self.has_column("sessions", "files_changed")? {
self.conn
.execute(
"ALTER TABLE sessions ADD COLUMN files_changed INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add files_changed column to sessions table")?;
}
if !self.has_column("sessions", "duration_secs")? {
self.conn
.execute(
"ALTER TABLE sessions ADD COLUMN duration_secs INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add duration_secs column to sessions table")?;
}
if !self.has_column("sessions", "cost_usd")? {
self.conn
.execute(
"ALTER TABLE sessions ADD COLUMN cost_usd REAL NOT NULL DEFAULT 0.0",
[],
)
.context("Failed to add cost_usd column to sessions table")?;
}
if !self.has_column("sessions", "last_heartbeat_at")? { if !self.has_column("sessions", "last_heartbeat_at")? {
self.conn self.conn
.execute("ALTER TABLE sessions ADD COLUMN last_heartbeat_at TEXT", []) .execute("ALTER TABLE sessions ADD COLUMN last_heartbeat_at TEXT", [])
@@ -568,24 +496,6 @@ impl StateStore {
.context("Failed to backfill last_heartbeat_at column")?; .context("Failed to backfill last_heartbeat_at column")?;
} }
if !self.has_column("sessions", "worktree_path")? {
self.conn
.execute("ALTER TABLE sessions ADD COLUMN worktree_path TEXT", [])
.context("Failed to add worktree_path column to sessions table")?;
}
if !self.has_column("sessions", "worktree_branch")? {
self.conn
.execute("ALTER TABLE sessions ADD COLUMN worktree_branch TEXT", [])
.context("Failed to add worktree_branch column to sessions table")?;
}
if !self.has_column("sessions", "worktree_base")? {
self.conn
.execute("ALTER TABLE sessions ADD COLUMN worktree_base TEXT", [])
.context("Failed to add worktree_base column to sessions table")?;
}
if !self.has_column("tool_log", "hook_event_id")? { if !self.has_column("tool_log", "hook_event_id")? {
self.conn self.conn
.execute("ALTER TABLE tool_log ADD COLUMN hook_event_id TEXT", []) .execute("ALTER TABLE tool_log ADD COLUMN hook_event_id TEXT", [])
@@ -802,103 +712,6 @@ impl StateStore {
Ok(()) Ok(())
} }
fn ensure_session_board_columns(&self) -> Result<()> {
if !self.has_column("session_board", "row_label")? {
self.conn
.execute("ALTER TABLE session_board ADD COLUMN row_label TEXT", [])
.context("Failed to add row_label column to session_board table")?;
}
if !self.has_column("session_board", "previous_lane")? {
self.conn
.execute("ALTER TABLE session_board ADD COLUMN previous_lane TEXT", [])
.context("Failed to add previous_lane column to session_board table")?;
}
if !self.has_column("session_board", "previous_row_label")? {
self.conn
.execute("ALTER TABLE session_board ADD COLUMN previous_row_label TEXT", [])
.context("Failed to add previous_row_label column to session_board table")?;
}
if !self.has_column("session_board", "column_index")? {
self.conn
.execute(
"ALTER TABLE session_board ADD COLUMN column_index INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add column_index column to session_board table")?;
}
if !self.has_column("session_board", "row_index")? {
self.conn
.execute(
"ALTER TABLE session_board ADD COLUMN row_index INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add row_index column to session_board table")?;
}
if !self.has_column("session_board", "stack_index")? {
self.conn
.execute(
"ALTER TABLE session_board ADD COLUMN stack_index INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add stack_index column to session_board table")?;
}
if !self.has_column("session_board", "progress_percent")? {
self.conn
.execute(
"ALTER TABLE session_board ADD COLUMN progress_percent INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add progress_percent column to session_board table")?;
}
if !self.has_column("session_board", "status_detail")? {
self.conn
.execute("ALTER TABLE session_board ADD COLUMN status_detail TEXT", [])
.context("Failed to add status_detail column to session_board table")?;
}
if !self.has_column("session_board", "movement_note")? {
self.conn
.execute("ALTER TABLE session_board ADD COLUMN movement_note TEXT", [])
.context("Failed to add movement_note column to session_board table")?;
}
if !self.has_column("session_board", "activity_kind")? {
self.conn
.execute("ALTER TABLE session_board ADD COLUMN activity_kind TEXT", [])
.context("Failed to add activity_kind column to session_board table")?;
}
if !self.has_column("session_board", "activity_note")? {
self.conn
.execute("ALTER TABLE session_board ADD COLUMN activity_note TEXT", [])
.context("Failed to add activity_note column to session_board table")?;
}
if !self.has_column("session_board", "handoff_backlog")? {
self.conn
.execute(
"ALTER TABLE session_board ADD COLUMN handoff_backlog INTEGER NOT NULL DEFAULT 0",
[],
)
.context("Failed to add handoff_backlog column to session_board table")?;
}
if !self.has_column("session_board", "conflict_signal")? {
self.conn
.execute("ALTER TABLE session_board ADD COLUMN conflict_signal TEXT", [])
.context("Failed to add conflict_signal column to session_board table")?;
}
Ok(())
}
fn has_column(&self, table: &str, column: &str) -> Result<bool> { fn has_column(&self, table: &str, column: &str) -> Result<bool> {
let pragma = format!("PRAGMA table_info({table})"); let pragma = format!("PRAGMA table_info({table})");
let mut stmt = self.conn.prepare(&pragma)?; let mut stmt = self.conn.prepare(&pragma)?;
@@ -976,7 +789,6 @@ impl StateStore {
session.last_heartbeat_at.to_rfc3339(), session.last_heartbeat_at.to_rfc3339(),
], ],
)?; )?;
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -1097,7 +909,6 @@ impl StateStore {
anyhow::bail!("Session not found: {session_id}"); anyhow::bail!("Session not found: {session_id}");
} }
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -1138,7 +949,6 @@ impl StateStore {
anyhow::bail!("Session not found: {session_id}"); anyhow::bail!("Session not found: {session_id}");
} }
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -1160,7 +970,6 @@ impl StateStore {
anyhow::bail!("Session not found: {session_id}"); anyhow::bail!("Session not found: {session_id}");
} }
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -1194,7 +1003,6 @@ impl StateStore {
anyhow::bail!("Session not found: {session_id}"); anyhow::bail!("Session not found: {session_id}");
} }
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -1222,7 +1030,6 @@ impl StateStore {
anyhow::bail!("Session not found: {session_id}"); anyhow::bail!("Session not found: {session_id}");
} }
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -1579,7 +1386,6 @@ impl StateStore {
session_id, session_id,
], ],
)?; )?;
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -1631,7 +1437,6 @@ impl StateStore {
} }
} }
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -1717,7 +1522,6 @@ impl StateStore {
)?; )?;
} }
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -2072,7 +1876,6 @@ impl StateStore {
WHERE id = ?2", WHERE id = ?2",
rusqlite::params![chrono::Utc::now().to_rfc3339(), session_id], rusqlite::params![chrono::Utc::now().to_rfc3339(), session_id],
)?; )?;
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -2176,46 +1979,6 @@ impl StateStore {
Ok(harnesses) Ok(harnesses)
} }
pub fn list_session_board_meta(&self) -> Result<HashMap<String, SessionBoardMeta>> {
let mut stmt = self.conn.prepare(
"SELECT session_id, lane, project, feature, issue, row_label,
previous_lane, previous_row_label,
column_index, row_index, stack_index, progress_percent,
status_detail, movement_note, activity_kind, activity_note,
handoff_backlog, conflict_signal
FROM session_board",
)?;
let meta = stmt
.query_map([], |row| {
Ok((
row.get::<_, String>(0)?,
SessionBoardMeta {
lane: row.get(1)?,
project: row.get(2)?,
feature: row.get(3)?,
issue: row.get(4)?,
row_label: row.get(5)?,
previous_lane: row.get(6)?,
previous_row_label: row.get(7)?,
column_index: row.get(8)?,
row_index: row.get(9)?,
stack_index: row.get(10)?,
progress_percent: row.get(11)?,
status_detail: row.get(12)?,
movement_note: row.get(13)?,
activity_kind: row.get(14)?,
activity_note: row.get(15)?,
handoff_backlog: row.get(16)?,
conflict_signal: row.get(17)?,
},
))
})?
.collect::<Result<HashMap<_, _>, _>>()?;
Ok(meta)
}
pub fn get_session_harness_info(&self, session_id: &str) -> Result<Option<SessionHarnessInfo>> { pub fn get_session_harness_info(&self, session_id: &str) -> Result<Option<SessionHarnessInfo>> {
let mut stmt = self.conn.prepare( let mut stmt = self.conn.prepare(
"SELECT harness, detected_harnesses_json, agent_type, working_dir "SELECT harness, detected_harnesses_json, agent_type, working_dir
@@ -2245,94 +2008,6 @@ impl StateStore {
Ok(self.list_sessions()?.into_iter().next()) Ok(self.list_sessions()?.into_iter().next())
} }
fn refresh_session_board_meta(&self) -> Result<()> {
self.conn.execute(
"DELETE FROM session_board
WHERE session_id NOT IN (SELECT id FROM sessions)",
[],
)?;
let existing_meta = self.list_session_board_meta().unwrap_or_default();
let sessions = self.list_sessions()?;
let board_meta = derive_board_meta_map(&sessions);
let now = chrono::Utc::now().to_rfc3339();
for session in sessions {
let mut meta = board_meta
.get(&session.id)
.cloned()
.unwrap_or_else(|| SessionBoardMeta {
lane: board_lane_for_state(&session.state).to_string(),
..SessionBoardMeta::default()
});
if let Some(previous) = existing_meta.get(&session.id) {
annotate_board_motion(&mut meta, previous);
}
if let Some((activity_kind, activity_note)) =
self.latest_task_handoff_activity(&session.id)?
{
meta.activity_kind = Some(activity_kind);
meta.activity_note = Some(activity_note);
} else {
meta.activity_kind = None;
meta.activity_note = None;
}
meta.handoff_backlog = self.unread_task_handoff_count(&session.id)? as i64;
self.conn.execute(
"INSERT INTO session_board (
session_id, lane, project, feature, issue, row_label,
previous_lane, previous_row_label,
column_index, row_index, stack_index, progress_percent,
status_detail, movement_note, activity_kind, activity_note,
handoff_backlog, conflict_signal, updated_at
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19)
ON CONFLICT(session_id) DO UPDATE SET
lane = excluded.lane,
project = excluded.project,
feature = excluded.feature,
issue = excluded.issue,
row_label = excluded.row_label,
previous_lane = excluded.previous_lane,
previous_row_label = excluded.previous_row_label,
column_index = excluded.column_index,
row_index = excluded.row_index,
stack_index = excluded.stack_index,
progress_percent = excluded.progress_percent,
status_detail = excluded.status_detail,
movement_note = excluded.movement_note,
activity_kind = excluded.activity_kind,
activity_note = excluded.activity_note,
handoff_backlog = excluded.handoff_backlog,
conflict_signal = excluded.conflict_signal,
updated_at = excluded.updated_at",
rusqlite::params![
session.id,
meta.lane,
meta.project,
meta.feature,
meta.issue,
meta.row_label,
meta.previous_lane,
meta.previous_row_label,
meta.column_index,
meta.row_index,
meta.stack_index,
meta.progress_percent,
meta.status_detail,
meta.movement_note,
meta.activity_kind,
meta.activity_note,
meta.handoff_backlog,
meta.conflict_signal,
now,
],
)?;
}
Ok(())
}
pub fn get_session(&self, id: &str) -> Result<Option<Session>> { pub fn get_session(&self, id: &str) -> Result<Option<Session>> {
let sessions = self.list_sessions()?; let sessions = self.list_sessions()?;
Ok(sessions Ok(sessions
@@ -2363,7 +2038,6 @@ impl StateStore {
anyhow::bail!("Session not found: {session_id}"); anyhow::bail!("Session not found: {session_id}");
} }
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -2374,7 +2048,6 @@ impl StateStore {
rusqlite::params![from, to, content, msg_type, chrono::Utc::now().to_rfc3339()], rusqlite::params![from, to, content, msg_type, chrono::Utc::now().to_rfc3339()],
)?; )?;
self.sync_context_graph_message(from, to, content, msg_type)?; self.sync_context_graph_message(from, to, content, msg_type)?;
self.refresh_session_board_meta()?;
Ok(()) Ok(())
} }
@@ -2645,7 +2318,6 @@ impl StateStore {
rusqlite::params![session_id], rusqlite::params![session_id],
)?; )?;
self.refresh_session_board_meta()?;
Ok(updated) Ok(updated)
} }
@@ -2655,7 +2327,6 @@ impl StateStore {
rusqlite::params![message_id], rusqlite::params![message_id],
)?; )?;
self.refresh_session_board_meta()?;
Ok(updated) Ok(updated)
} }
@@ -2674,75 +2345,6 @@ impl StateStore {
.map_err(Into::into) .map_err(Into::into)
} }
fn latest_task_handoff_activity(
&self,
session_id: &str,
) -> Result<Option<(String, String)>> {
let latest_handoff = self
.conn
.query_row(
"SELECT from_session, to_session, content
FROM messages
WHERE msg_type = 'task_handoff'
AND (from_session = ?1 OR to_session = ?1)
ORDER BY id DESC
LIMIT 1",
rusqlite::params![session_id],
|row| {
Ok((
row.get::<_, String>(0)?,
row.get::<_, String>(1)?,
row.get::<_, String>(2)?,
))
},
)
.optional()?;
Ok(latest_handoff.and_then(|(from_session, to_session, content)| {
let context = extract_task_handoff_context(&content)?;
let routing_suffix = routing_activity_suffix(&context);
if session_id == to_session {
Some((
"received".to_string(),
format!(
"Received from {}{}",
short_session_ref(&from_session),
routing_suffix
.map(|value| format!(" | {value}"))
.unwrap_or_default()
),
))
} else if session_id == from_session {
let (kind, base) = match routing_suffix {
Some("spawned") => {
("spawned", format!("Spawned {}", short_session_ref(&to_session)))
}
Some("spawned fallback") => (
"spawned_fallback",
format!("Spawned fallback {}", short_session_ref(&to_session)),
),
_ => (
"delegated",
format!("Delegated to {}", short_session_ref(&to_session)),
),
};
Some((
kind.to_string(),
format!(
"{base}{}",
routing_suffix
.filter(|value| !value.starts_with("spawned"))
.map(|value| format!(" | {value}"))
.unwrap_or_default()
),
))
} else {
None
}
}))
}
pub fn insert_decision( pub fn insert_decision(
&self, &self,
session_id: &str, session_id: &str,
@@ -4260,411 +3862,6 @@ fn file_activity_action_value(action: &FileActivityAction) -> &'static str {
} }
} }
fn board_lane_for_state(state: &SessionState) -> &'static str {
match state {
SessionState::Pending => "Inbox",
SessionState::Running => "In Progress",
SessionState::Idle => "Review",
SessionState::Stale | SessionState::Failed => "Blocked",
SessionState::Completed => "Done",
SessionState::Stopped => "Stopped",
}
}
fn derive_board_scope(session: &Session) -> (Option<String>, Option<String>, Option<String>) {
let project = extract_labeled_scope(&session.task, &["project", "roadmap", "epic"]);
let feature = extract_labeled_scope(&session.task, &["feature", "workflow", "flow"]);
let issue = extract_issue_reference(&session.task);
(project, feature, issue)
}
fn derive_board_meta_map(sessions: &[Session]) -> HashMap<String, SessionBoardMeta> {
let conflict_signals = derive_board_conflict_signals(sessions);
let scopes = sessions
.iter()
.map(|session| (session.id.clone(), derive_board_scope(session)))
.collect::<HashMap<_, _>>();
let mut row_specs = scopes
.iter()
.map(|(session_id, (project, feature, issue))| {
let row_label = issue
.clone()
.or_else(|| feature.clone())
.or_else(|| project.clone())
.or_else(|| {
sessions
.iter()
.find(|session| &session.id == session_id)
.and_then(|session| session.worktree.as_ref())
.map(|worktree| worktree.branch.clone())
})
.unwrap_or_else(|| "General".to_string());
let row_rank = if issue.is_some() {
0
} else if feature.is_some() {
1
} else if project.is_some() {
2
} else {
3
};
(session_id.clone(), row_label, row_rank)
})
.collect::<Vec<_>>();
row_specs.sort_by(|left, right| {
left.2
.cmp(&right.2)
.then_with(|| left.1.to_ascii_lowercase().cmp(&right.1.to_ascii_lowercase()))
.then_with(|| left.0.cmp(&right.0))
});
let mut row_indices = HashMap::new();
let mut next_row_index = 0_i64;
for (_, row_label, row_rank) in &row_specs {
let key = (*row_rank, row_label.clone());
if let std::collections::hash_map::Entry::Vacant(entry) = row_indices.entry(key) {
entry.insert(next_row_index);
next_row_index += 1;
}
}
let mut stack_counts: HashMap<(i64, i64), i64> = HashMap::new();
let mut board_meta = HashMap::new();
for session in sessions {
let (project, feature, issue) = scopes
.get(&session.id)
.cloned()
.unwrap_or((None, None, None));
let (_, row_label, row_rank) = row_specs
.iter()
.find(|(session_id, _, _)| session_id == &session.id)
.cloned()
.unwrap_or_else(|| (session.id.clone(), "General".to_string(), 4));
let column_index = board_column_index(&session.state);
let row_index = row_indices
.get(&(row_rank, row_label.clone()))
.copied()
.unwrap_or_default();
let stack_index = {
let entry = stack_counts.entry((column_index, row_index)).or_insert(0);
let current = *entry;
*entry += 1;
current
};
board_meta.insert(
session.id.clone(),
SessionBoardMeta {
lane: board_lane_for_state(&session.state).to_string(),
project,
feature,
issue,
row_label: Some(row_label),
previous_lane: None,
previous_row_label: None,
column_index,
row_index,
stack_index,
progress_percent: derive_board_progress_percent(session),
status_detail: derive_board_status_detail(session),
movement_note: None,
activity_kind: None,
activity_note: None,
handoff_backlog: 0,
conflict_signal: conflict_signals.get(&session.id).cloned(),
},
);
}
board_meta
}
fn board_column_index(state: &SessionState) -> i64 {
match state {
SessionState::Pending => 0,
SessionState::Running => 1,
SessionState::Idle => 2,
SessionState::Stale | SessionState::Failed => 3,
SessionState::Completed => 4,
SessionState::Stopped => 5,
}
}
fn derive_board_progress_percent(session: &Session) -> i64 {
match session.state {
SessionState::Pending => 10,
SessionState::Running => {
if session.metrics.files_changed > 0 {
60
} else if session.worktree.is_some() || session.metrics.tool_calls > 0 {
45
} else {
25
}
}
SessionState::Idle => 85,
SessionState::Stale => 55,
SessionState::Completed => 100,
SessionState::Failed => 65,
SessionState::Stopped => 0,
}
}
fn derive_board_status_detail(session: &Session) -> Option<String> {
let detail = match session.state {
SessionState::Pending => "Queued",
SessionState::Running => {
if session.metrics.files_changed > 0 {
"Actively editing"
} else if session.worktree.is_some() {
"Scoping"
} else {
"Booting"
}
}
SessionState::Idle => "Awaiting review",
SessionState::Stale => "Needs heartbeat",
SessionState::Completed => "Task complete",
SessionState::Failed => "Blocked by failure",
SessionState::Stopped => "Stopped",
};
Some(detail.to_string())
}
fn annotate_board_motion(current: &mut SessionBoardMeta, previous: &SessionBoardMeta) {
if previous.lane != current.lane {
current.previous_lane = Some(previous.lane.clone());
current.previous_row_label = previous.row_label.clone();
current.movement_note = Some(match current.lane.as_str() {
"Blocked" => "Blocked".to_string(),
"Done" => "Completed".to_string(),
_ => format!("Moved {} -> {}", previous.lane, current.lane),
});
return;
}
if previous.row_label != current.row_label {
let from = previous
.row_label
.clone()
.unwrap_or_else(|| "General".to_string());
let to = current
.row_label
.clone()
.unwrap_or_else(|| "General".to_string());
current.previous_lane = Some(previous.lane.clone());
current.previous_row_label = previous.row_label.clone();
current.movement_note = Some(format!("Retargeted {from} -> {to}"));
}
}
fn extract_labeled_scope(task: &str, labels: &[&str]) -> Option<String> {
let lowered = task.to_ascii_lowercase();
for label in labels {
if let Some(index) = lowered.find(label) {
let mut tail = task.get(index + label.len()..)?.trim_start_matches([' ', ':', '-', '#']);
if tail.is_empty() {
continue;
}
if let Some((candidate, _)) = tail
.split_once('|')
.or_else(|| tail.split_once(';'))
.or_else(|| tail.split_once(','))
.or_else(|| tail.split_once('\n'))
{
tail = candidate;
}
let words = tail
.split_whitespace()
.take(4)
.collect::<Vec<_>>()
.join(" ")
.trim()
.trim_matches(|ch: char| matches!(ch, '.' | ',' | ';' | ':' | '|'))
.to_string();
if !words.is_empty() {
return Some(words);
}
}
}
None
}
fn extract_issue_reference(task: &str) -> Option<String> {
let tokens = task
.split(|ch: char| ch.is_whitespace() || matches!(ch, ',' | ';' | ':' | '(' | ')'))
.filter(|token| !token.is_empty());
for token in tokens {
if let Some(stripped) = token.strip_prefix('#') {
if !stripped.is_empty() && stripped.chars().all(|ch| ch.is_ascii_digit()) {
return Some(format!("#{stripped}"));
}
}
if let Some((prefix, suffix)) = token.split_once('-') {
if !prefix.is_empty()
&& !suffix.is_empty()
&& prefix.chars().all(|ch| ch.is_ascii_uppercase())
&& suffix.chars().all(|ch| ch.is_ascii_digit())
{
return Some(token.trim_matches('.').to_string());
}
}
}
None
}
fn derive_board_conflict_signals(sessions: &[Session]) -> HashMap<String, String> {
let active_sessions = sessions
.iter()
.filter(|session| {
matches!(
session.state,
SessionState::Pending | SessionState::Running | SessionState::Idle | SessionState::Stale
)
})
.collect::<Vec<_>>();
let mut sessions_by_branch: HashMap<String, Vec<&Session>> = HashMap::new();
let mut sessions_by_task: HashMap<String, Vec<&Session>> = HashMap::new();
let mut sessions_by_scope: HashMap<String, Vec<&Session>> = HashMap::new();
for session in active_sessions {
if let Some(worktree) = session.worktree.as_ref() {
sessions_by_branch
.entry(worktree.branch.clone())
.or_default()
.push(session);
}
sessions_by_task
.entry(session.task.trim().to_ascii_lowercase())
.or_default()
.push(session);
let (project, feature, issue) = derive_board_scope(session);
if let Some(scope) = issue.or(feature).or(project).filter(|scope| !scope.is_empty()) {
sessions_by_scope.entry(scope).or_default().push(session);
}
}
let mut signals = HashMap::new();
for (branch, grouped_sessions) in sessions_by_branch {
if grouped_sessions.len() < 2 {
continue;
}
for session in grouped_sessions {
append_conflict_signal(&mut signals, &session.id, format!("Shared branch {branch}"));
}
}
for (task, grouped_sessions) in sessions_by_task {
if grouped_sessions.len() < 2 {
continue;
}
for session in grouped_sessions {
append_conflict_signal(
&mut signals,
&session.id,
format!("Shared task {}", truncate_task_for_signal(&task)),
);
}
}
for (scope, grouped_sessions) in sessions_by_scope {
if grouped_sessions.len() < 2 {
continue;
}
for session in grouped_sessions {
append_conflict_signal(
&mut signals,
&session.id,
format!("Shared scope {}", truncate_task_for_signal(&scope)),
);
}
}
signals
}
fn append_conflict_signal(
signals: &mut HashMap<String, String>,
session_id: &str,
next_signal: String,
) {
let entry = signals.entry(session_id.to_string()).or_default();
if entry.is_empty() {
*entry = next_signal;
return;
}
if !entry.split("; ").any(|existing| existing == next_signal) {
entry.push_str("; ");
entry.push_str(&next_signal);
}
}
fn short_session_ref(session_id: &str) -> String {
if session_id.chars().count() <= 12 {
session_id.to_string()
} else {
session_id.chars().take(8).collect()
}
}
fn routing_activity_suffix(context: &str) -> Option<&'static str> {
let normalized = context.to_ascii_lowercase();
if normalized.contains("reused idle delegate") {
Some("reused idle")
} else if normalized.contains("reused active delegate") {
Some("reused active")
} else if normalized.contains("spawned fallback delegate") {
Some("spawned fallback")
} else if normalized.contains("spawned new delegate") {
Some("spawned")
} else {
None
}
}
fn extract_task_handoff_context(content: &str) -> Option<String> {
if let Some(crate::comms::MessageType::TaskHandoff { context, .. }) = crate::comms::parse(content)
{
return Some(context);
}
let value: serde_json::Value = serde_json::from_str(content).ok()?;
value
.get("context")
.and_then(|context| context.as_str())
.map(ToOwned::to_owned)
}
fn truncate_task_for_signal(task: &str) -> String {
const LIMIT: usize = 28;
let trimmed = task.trim();
let count = trimmed.chars().count();
if count <= LIMIT {
trimmed.to_string()
} else {
format!("{}...", trimmed.chars().take(LIMIT - 3).collect::<String>())
}
}
fn map_conflict_incident(row: &rusqlite::Row<'_>) -> rusqlite::Result<ConflictIncident> { fn map_conflict_incident(row: &rusqlite::Row<'_>) -> rusqlite::Result<ConflictIncident> {
let created_at = parse_timestamp_column(row.get::<_, String>(11)?, 11)?; let created_at = parse_timestamp_column(row.get::<_, String>(11)?, 11)?;
let updated_at = parse_timestamp_column(row.get::<_, String>(12)?, 12)?; let updated_at = parse_timestamp_column(row.get::<_, String>(12)?, 12)?;

View File

@@ -24,7 +24,7 @@ use crate::session::output::{
use crate::session::store::{DaemonActivity, FileActivityOverlap, StateStore}; use crate::session::store::{DaemonActivity, FileActivityOverlap, StateStore};
use crate::session::{ use crate::session::{
ContextObservationPriority, DecisionLogEntry, FileActivityEntry, Session, SessionGrouping, ContextObservationPriority, DecisionLogEntry, FileActivityEntry, Session, SessionGrouping,
SessionBoardMeta, SessionHarnessInfo, SessionMessage, SessionState, SessionHarnessInfo, SessionMessage, SessionState,
}; };
use crate::worktree; use crate::worktree;
@@ -93,7 +93,6 @@ pub struct Dashboard {
approval_queue_counts: HashMap<String, usize>, approval_queue_counts: HashMap<String, usize>,
approval_queue_preview: Vec<SessionMessage>, approval_queue_preview: Vec<SessionMessage>,
handoff_backlog_counts: HashMap<String, usize>, handoff_backlog_counts: HashMap<String, usize>,
board_meta_by_session: HashMap<String, SessionBoardMeta>,
worktree_health_by_session: HashMap<String, worktree::WorktreeHealth>, worktree_health_by_session: HashMap<String, worktree::WorktreeHealth>,
global_handoff_backlog_leads: usize, global_handoff_backlog_leads: usize,
global_handoff_backlog_messages: usize, global_handoff_backlog_messages: usize,
@@ -180,7 +179,6 @@ enum Pane {
Sessions, Sessions,
Output, Output,
Metrics, Metrics,
Board,
Log, Log,
} }
@@ -335,7 +333,7 @@ impl PaneAreas {
match pane { match pane {
Pane::Sessions => self.sessions = area, Pane::Sessions => self.sessions = area,
Pane::Output => self.output = Some(area), Pane::Output => self.output = Some(area),
Pane::Metrics | Pane::Board => self.metrics = Some(area), Pane::Metrics => self.metrics = Some(area),
Pane::Log => self.log = Some(area), Pane::Log => self.log = Some(area),
} }
} }
@@ -555,7 +553,6 @@ impl Dashboard {
approval_queue_counts: HashMap::new(), approval_queue_counts: HashMap::new(),
approval_queue_preview: Vec::new(), approval_queue_preview: Vec::new(),
handoff_backlog_counts: HashMap::new(), handoff_backlog_counts: HashMap::new(),
board_meta_by_session: HashMap::new(),
worktree_health_by_session: HashMap::new(), worktree_health_by_session: HashMap::new(),
global_handoff_backlog_leads: 0, global_handoff_backlog_leads: 0,
global_handoff_backlog_messages: 0, global_handoff_backlog_messages: 0,
@@ -622,7 +619,6 @@ impl Dashboard {
dashboard.unread_message_counts = dashboard.db.unread_message_counts().unwrap_or_default(); dashboard.unread_message_counts = dashboard.db.unread_message_counts().unwrap_or_default();
dashboard.sync_approval_queue(); dashboard.sync_approval_queue();
dashboard.sync_handoff_backlog_counts(); dashboard.sync_handoff_backlog_counts();
dashboard.sync_board_meta();
dashboard.sync_global_handoff_backlog(); dashboard.sync_global_handoff_backlog();
dashboard.sync_selected_output(); dashboard.sync_selected_output();
dashboard.sync_selected_diff(); dashboard.sync_selected_diff();
@@ -1298,18 +1294,10 @@ impl Dashboard {
} }
fn render_metrics(&mut self, frame: &mut Frame, area: Rect) { fn render_metrics(&mut self, frame: &mut Frame, area: Rect) {
let side_pane = if self.selected_pane == Pane::Board {
Pane::Board
} else {
Pane::Metrics
};
let block = Block::default() let block = Block::default()
.borders(Borders::ALL) .borders(Borders::ALL)
.title(match side_pane { .title(" Metrics ")
Pane::Board => " Board ", .border_style(self.pane_border_style(Pane::Metrics));
_ => " Metrics ",
})
.border_style(self.pane_border_style(side_pane));
let inner = block.inner(area); let inner = block.inner(area);
frame.render_widget(block, area); frame.render_widget(block, area);
@@ -1317,17 +1305,6 @@ impl Dashboard {
return; return;
} }
if side_pane == Pane::Board {
frame.render_widget(
Paragraph::new(self.board_text())
.scroll((self.metrics_scroll_offset as u16, 0))
.wrap(Wrap { trim: true }),
inner,
);
self.sync_metrics_scroll(inner.height as usize);
return;
}
let chunks = Layout::default() let chunks = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
.constraints([ .constraints([
@@ -1643,7 +1620,7 @@ impl Dashboard {
return; return;
}; };
if !self.is_pane_visible(target) { if !self.visible_panes().contains(&target) {
self.set_operator_note(format!( self.set_operator_note(format!(
"{} pane is not visible", "{} pane is not visible",
target.title().to_lowercase() target.title().to_lowercase()
@@ -1725,7 +1702,6 @@ impl Dashboard {
crossterm::event::KeyCode::Char('2') => self.focus_pane_number(2), crossterm::event::KeyCode::Char('2') => self.focus_pane_number(2),
crossterm::event::KeyCode::Char('3') => self.focus_pane_number(3), crossterm::event::KeyCode::Char('3') => self.focus_pane_number(3),
crossterm::event::KeyCode::Char('4') => self.focus_pane_number(4), crossterm::event::KeyCode::Char('4') => self.focus_pane_number(4),
crossterm::event::KeyCode::Char('5') => self.focus_pane_number(5),
crossterm::event::KeyCode::Char('+') | crossterm::event::KeyCode::Char('=') => { crossterm::event::KeyCode::Char('+') | crossterm::event::KeyCode::Char('=') => {
self.increase_pane_size() self.increase_pane_size()
} }
@@ -2041,7 +2017,7 @@ impl Dashboard {
self.output_scroll_offset = self.output_scroll_offset.saturating_add(1); self.output_scroll_offset = self.output_scroll_offset.saturating_add(1);
} }
} }
Pane::Metrics | Pane::Board => { Pane::Metrics => {
let max_scroll = self.max_metrics_scroll(); let max_scroll = self.max_metrics_scroll();
self.metrics_scroll_offset = self.metrics_scroll_offset =
self.metrics_scroll_offset.saturating_add(1).min(max_scroll); self.metrics_scroll_offset.saturating_add(1).min(max_scroll);
@@ -2081,7 +2057,7 @@ impl Dashboard {
self.output_scroll_offset = self.output_scroll_offset.saturating_sub(1); self.output_scroll_offset = self.output_scroll_offset.saturating_sub(1);
} }
Pane::Metrics | Pane::Board => { Pane::Metrics => {
self.metrics_scroll_offset = self.metrics_scroll_offset.saturating_sub(1); self.metrics_scroll_offset = self.metrics_scroll_offset.saturating_sub(1);
} }
Pane::Log => { Pane::Log => {
@@ -4097,7 +4073,6 @@ impl Dashboard {
}; };
self.sync_approval_queue(); self.sync_approval_queue();
self.sync_handoff_backlog_counts(); self.sync_handoff_backlog_counts();
self.sync_board_meta();
self.sync_worktree_health_by_session(); self.sync_worktree_health_by_session();
self.sync_session_state_notifications(); self.sync_session_state_notifications();
self.sync_approval_notifications(); self.sync_approval_notifications();
@@ -4503,7 +4478,7 @@ impl Dashboard {
} }
fn ensure_selected_pane_visible(&mut self) { fn ensure_selected_pane_visible(&mut self) {
if !self.is_pane_visible(self.selected_pane) { if !self.visible_panes().contains(&self.selected_pane) {
self.selected_pane = Pane::Sessions; self.selected_pane = Pane::Sessions;
} }
} }
@@ -4606,16 +4581,6 @@ impl Dashboard {
} }
} }
fn sync_board_meta(&mut self) {
self.board_meta_by_session = match self.db.list_session_board_meta() {
Ok(meta) => meta,
Err(error) => {
tracing::warn!("Failed to refresh board metadata: {error}");
HashMap::new()
}
};
}
fn sync_worktree_health_by_session(&mut self) { fn sync_worktree_health_by_session(&mut self) {
self.worktree_health_by_session.clear(); self.worktree_health_by_session.clear();
for session in &self.sessions { for session in &self.sessions {
@@ -6532,268 +6497,6 @@ impl Dashboard {
} }
} }
fn board_text(&self) -> String {
if self.sessions.is_empty() {
return "No sessions available.\n\nStart a session to populate the board.".to_string();
}
let mut lines = Vec::new();
lines.push(format!("Board snapshot | {} sessions", self.sessions.len()));
if let Some(session) = self.sessions.get(self.selected_session) {
let meta = self.board_meta_by_session.get(&session.id);
let branch = session_branch(session);
lines.push(format!(
"Focus {} {} | {} | {}{}",
board_presence_marker(session),
board_codename(session),
meta.map(|meta| meta.lane.as_str())
.unwrap_or_else(|| board_lane_label(&session.state)),
format_session_id(&session.id),
if branch == "-" {
String::new()
} else {
format!(" | {branch}")
}
));
lines.push(format!("Task {}", truncate_for_dashboard(&session.task, 48)));
if let Some(meta) = meta {
lines.push(format!(
"Progress {:>3}% {}",
meta.progress_percent,
board_progress_bar(meta.progress_percent)
));
if let Some(status_detail) = meta.status_detail.as_ref() {
lines.push(format!("Status {status_detail}"));
}
if let Some(movement_note) = meta.movement_note.as_ref() {
lines.push(format!("Event {movement_note}"));
}
if meta.handoff_backlog > 0 {
lines.push(format!("Inbox {} handoff(s)", meta.handoff_backlog));
}
if let Some(activity_note) = meta.activity_note.as_ref() {
lines.push(format!("Route {activity_note}"));
}
lines.push(format!(
"Coords C{} R{} S{}",
meta.column_index + 1,
meta.row_index + 1,
meta.stack_index + 1
));
if let Some(row_label) = meta.row_label.as_ref() {
lines.push(format!("Row {row_label}"));
}
if let Some(project) = meta.project.as_ref() {
lines.push(format!("Project {project}"));
}
if let Some(feature) = meta.feature.as_ref() {
lines.push(format!("Feature {feature}"));
}
if let Some(issue) = meta.issue.as_ref() {
lines.push(format!("Issue {issue}"));
}
}
}
let overlap_risks = self.board_overlap_risks();
if overlap_risks.is_empty() {
lines.push("Overlap risk clear".to_string());
} else {
lines.push("Overlap risk".to_string());
for risk in overlap_risks {
lines.push(format!("- {risk}"));
}
}
let lanes = ["Inbox", "In Progress", "Review", "Blocked", "Done", "Stopped"];
for label in lanes {
let mut lane_sessions = self
.sessions
.iter()
.filter_map(|session| {
let lane = self
.board_meta_by_session
.get(&session.id)
.map(|meta| meta.lane.as_str())
.unwrap_or_else(|| board_lane_label(&session.state));
if lane == label {
Some((session, self.board_meta_by_session.get(&session.id)))
} else {
None
}
})
.collect::<Vec<_>>();
if lane_sessions.is_empty() {
continue;
}
let mut row_risks: HashMap<(i64, String), Vec<String>> = HashMap::new();
let mut row_backlogs: HashMap<(i64, String), i64> = HashMap::new();
for (_, meta) in &lane_sessions {
let Some(meta) = meta else {
continue;
};
let key = (
meta.row_index,
meta.row_label
.clone()
.unwrap_or_else(|| "General".to_string()),
);
if let Some(conflict_signal) = meta.conflict_signal.as_ref() {
let entry = row_risks.entry(key.clone()).or_default();
for risk in conflict_signal.split("; ") {
if !entry.iter().any(|existing| existing == risk) {
entry.push(risk.to_string());
}
}
}
if meta.handoff_backlog > 0 {
*row_backlogs.entry(key).or_default() += meta.handoff_backlog;
}
}
lane_sessions.sort_by(|left, right| {
let left_meta = left.1.cloned().unwrap_or_default();
let right_meta = right.1.cloned().unwrap_or_default();
left_meta
.row_index
.cmp(&right_meta.row_index)
.then_with(|| left_meta.stack_index.cmp(&right_meta.stack_index))
.then_with(|| left.0.id.cmp(&right.0.id))
});
lines.push(String::new());
lines.push(format!("{label} ({})", lane_sessions.len()));
let mut current_row: Option<String> = None;
for (session, meta) in lane_sessions.into_iter().take(6) {
let meta = meta.cloned().unwrap_or_default();
let row_label = meta
.row_label
.clone()
.unwrap_or_else(|| "General".to_string());
if current_row.as_ref() != Some(&row_label) {
current_row = Some(row_label.clone());
let row_key = (meta.row_index, row_label.clone());
let row_conflict_summary = row_risks
.get(&row_key)
.filter(|risks| !risks.is_empty())
.map(|risks| truncate_for_dashboard(&risks.join(" + "), 42));
let row_backlog = row_backlogs.get(&row_key).copied().unwrap_or(0);
let row_pressure_summary = if row_backlog > 0 {
Some(format!("{} handoff(s)", row_backlog))
} else {
None
};
let row_marker = if row_conflict_summary.is_some() {
"!"
} else if row_pressure_summary.is_some() {
"+"
} else {
"-"
};
lines.push(format!(
" {} Row {} | {}{}{}",
row_marker,
meta.row_index + 1,
row_label,
row_conflict_summary
.map(|summary| format!(" | {summary}"))
.unwrap_or_default(),
row_pressure_summary
.map(|summary| format!(" | {summary}"))
.unwrap_or_default()
));
}
let branch = session_branch(session);
let branch_suffix = if branch == "-" {
String::new()
} else {
format!(" | {branch}")
};
let activity_suffix = meta
.activity_note
.as_ref()
.map(|note| format!(" | {}", truncate_for_dashboard(note, 26)))
.unwrap_or_default();
let backlog_suffix = if meta.handoff_backlog > 0 {
format!(" | inbox {}", meta.handoff_backlog)
} else {
String::new()
};
let kind_marker = board_activity_marker(&meta);
lines.push(format!(
" {}{} {} {} {} [{}] {:>3}% {} | {}{}{}{}",
board_motion_marker(&meta),
kind_marker,
board_presence_marker(session),
board_codename(session),
format_session_id(&session.id),
session.agent_type,
meta.progress_percent,
board_progress_bar(meta.progress_percent),
truncate_for_dashboard(meta.status_detail.as_deref().unwrap_or(&session.task), 18),
activity_suffix,
backlog_suffix,
branch_suffix
));
}
}
lines.join("\n")
}
fn board_overlap_risks(&self) -> Vec<String> {
let mut risks = self
.board_meta_by_session
.values()
.filter_map(|meta| meta.conflict_signal.clone())
.collect::<Vec<_>>();
if risks.is_empty() {
let mut duplicate_branches: HashMap<String, Vec<String>> = HashMap::new();
let mut duplicate_tasks: HashMap<String, Vec<String>> = HashMap::new();
for session in self.sessions.iter().filter(|session| {
matches!(
session.state,
SessionState::Pending
| SessionState::Running
| SessionState::Idle
| SessionState::Stale
)
}) {
if let Some(worktree) = session.worktree.as_ref() {
duplicate_branches
.entry(worktree.branch.clone())
.or_default()
.push(format_session_id(&session.id));
}
duplicate_tasks
.entry(session.task.trim().to_ascii_lowercase())
.or_default()
.push(format_session_id(&session.id));
}
for (branch, sessions) in duplicate_branches {
if sessions.len() >= 2 {
risks.push(format!("Shared branch {branch}: {}", sessions.join(", ")));
}
}
for (task, sessions) in duplicate_tasks {
if sessions.len() >= 2 {
risks.push(format!(
"Shared task {}: {}",
truncate_for_dashboard(&task, 32),
sessions.join(", ")
));
}
}
}
risks.sort();
risks.dedup();
risks
}
fn aggregate_cost_summary(&self) -> (String, Style) { fn aggregate_cost_summary(&self) -> (String, Style) {
let aggregate = self.aggregate_usage(); let aggregate = self.aggregate_usage();
let thresholds = self.cfg.effective_budget_alert_thresholds(); let thresholds = self.cfg.effective_budget_alert_thresholds();
@@ -7071,9 +6774,7 @@ impl Dashboard {
} }
fn visible_detail_panes(&self) -> Vec<Pane> { fn visible_detail_panes(&self) -> Vec<Pane> {
self.layout_panes() self.visible_panes()
.into_iter()
.filter(|pane| !self.collapsed_panes.contains(pane))
.into_iter() .into_iter()
.filter(|pane| *pane != Pane::Sessions) .filter(|pane| *pane != Pane::Sessions)
.collect() .collect()
@@ -7118,19 +6819,6 @@ impl Dashboard {
} }
} }
fn board_pane_visible(&self) -> bool {
self.cfg.pane_layout == PaneLayout::Grid
&& !self.collapsed_panes.contains(&Pane::Metrics)
&& self.layout_panes().contains(&Pane::Metrics)
}
fn is_pane_visible(&self, pane: Pane) -> bool {
match pane {
Pane::Board => self.board_pane_visible(),
_ => self.visible_panes().contains(&pane),
}
}
fn theme_palette(&self) -> ThemePalette { fn theme_palette(&self) -> ThemePalette {
match self.cfg.theme { match self.cfg.theme {
Theme::Dark => ThemePalette { Theme::Dark => ThemePalette {
@@ -7198,7 +6886,6 @@ impl Pane {
Pane::Sessions => "Sessions", Pane::Sessions => "Sessions",
Pane::Output => "Output", Pane::Output => "Output",
Pane::Metrics => "Metrics", Pane::Metrics => "Metrics",
Pane::Board => "Board",
Pane::Log => "Log", Pane::Log => "Log",
} }
} }
@@ -7209,7 +6896,6 @@ impl Pane {
2 => Some(Self::Output), 2 => Some(Self::Output),
3 => Some(Self::Metrics), 3 => Some(Self::Metrics),
4 => Some(Self::Log), 4 => Some(Self::Log),
5 => Some(Self::Board),
_ => None, _ => None,
} }
} }
@@ -7219,8 +6905,7 @@ impl Pane {
Self::Sessions => 1, Self::Sessions => 1,
Self::Output => 2, Self::Output => 2,
Self::Metrics => 3, Self::Metrics => 3,
Self::Board => 4, Self::Log => 4,
Self::Log => 5,
} }
} }
} }
@@ -7230,7 +6915,6 @@ fn pane_rect(pane_areas: &PaneAreas, pane: Pane) -> Option<Rect> {
Pane::Sessions => Some(pane_areas.sessions), Pane::Sessions => Some(pane_areas.sessions),
Pane::Output => pane_areas.output, Pane::Output => pane_areas.output,
Pane::Metrics => pane_areas.metrics, Pane::Metrics => pane_areas.metrics,
Pane::Board => pane_areas.metrics,
Pane::Log => pane_areas.log, Pane::Log => pane_areas.log,
} }
} }
@@ -8563,17 +8247,6 @@ fn diff_addition_word_style() -> Style {
.add_modifier(Modifier::BOLD) .add_modifier(Modifier::BOLD)
} }
fn board_lane_label(state: &SessionState) -> &'static str {
match state {
SessionState::Pending => "Inbox",
SessionState::Running => "In Progress",
SessionState::Idle => "Review",
SessionState::Stale | SessionState::Failed => "Blocked",
SessionState::Completed => "Done",
SessionState::Stopped => "Stopped",
}
}
fn session_state_label(state: &SessionState) -> &'static str { fn session_state_label(state: &SessionState) -> &'static str {
match state { match state {
SessionState::Pending => "Pending", SessionState::Pending => "Pending",
@@ -8598,25 +8271,6 @@ fn session_state_color(state: &SessionState) -> Color {
} }
} }
fn board_codename(session: &Session) -> String {
const ADJECTIVES: &[&str] = &[
"Amber", "Cinder", "Moss", "Nova", "Sable", "Slate", "Swift", "Talon",
];
const NOUNS: &[&str] = &[
"Fox", "Kite", "Lynx", "Otter", "Rook", "Sprite", "Wisp", "Wolf",
];
let seed = session
.id
.bytes()
.fold(0usize, |acc, byte| acc.wrapping_mul(33).wrapping_add(byte as usize));
format!(
"{} {}",
ADJECTIVES[seed % ADJECTIVES.len()],
NOUNS[(seed / ADJECTIVES.len()) % NOUNS.len()]
)
}
fn file_activity_summary(entry: &FileActivityEntry) -> String { fn file_activity_summary(entry: &FileActivityEntry) -> String {
let mut summary = format!( let mut summary = format!(
"{} {}", "{} {}",
@@ -9394,44 +9048,6 @@ fn session_branch(session: &Session) -> String {
.unwrap_or_else(|| "-".to_string()) .unwrap_or_else(|| "-".to_string())
} }
fn board_progress_bar(progress_percent: i64) -> String {
let clamped = progress_percent.clamp(0, 100);
let filled = ((clamped + 9) / 10) as usize;
let empty = 10usize.saturating_sub(filled);
format!("[{}{}]", "#".repeat(filled), ".".repeat(empty))
}
fn board_presence_marker(session: &Session) -> String {
let codename = board_codename(session);
let initials = codename
.split_whitespace()
.filter_map(|part| part.chars().next())
.take(2)
.collect::<String>()
.to_ascii_uppercase();
format!("@{initials}")
}
fn board_motion_marker(meta: &SessionBoardMeta) -> &'static str {
match meta.movement_note.as_deref() {
Some("Blocked") => "x",
Some("Completed") => "*",
Some(note) if note.starts_with("Moved ") => ">",
Some(note) if note.starts_with("Retargeted ") => "~",
_ => ".",
}
}
fn board_activity_marker(meta: &SessionBoardMeta) -> &'static str {
match meta.activity_kind.as_deref() {
Some("received") => "<",
Some("delegated") => ">",
Some("spawned") => "+",
Some("spawned_fallback") => "#",
_ => "",
}
}
fn format_duration(duration_secs: u64) -> String { fn format_duration(duration_secs: u64) -> String {
let hours = duration_secs / 3600; let hours = duration_secs / 3600;
let minutes = (duration_secs % 3600) / 60; let minutes = (duration_secs % 3600) / 60;
@@ -14601,11 +14217,6 @@ diff --git a/src/lib.rs b/src/lib.rs
#[test] #[test]
fn pane_command_mode_sets_layout() { fn pane_command_mode_sets_layout() {
let tempdir = std::env::temp_dir().join(format!("ecc2-pane-command-{}", Uuid::new_v4()));
std::fs::create_dir_all(&tempdir).unwrap();
let previous_home = std::env::var_os("HOME");
std::env::set_var("HOME", &tempdir);
let mut dashboard = test_dashboard(Vec::new(), 0); let mut dashboard = test_dashboard(Vec::new(), 0);
dashboard.cfg.pane_layout = PaneLayout::Horizontal; dashboard.cfg.pane_layout = PaneLayout::Horizontal;
@@ -14620,22 +14231,10 @@ diff --git a/src/lib.rs b/src/lib.rs
.operator_note .operator_note
.as_deref() .as_deref()
.is_some_and(|note| note.contains("pane layout set to grid | saved to "))); .is_some_and(|note| note.contains("pane layout set to grid | saved to ")));
if let Some(home) = previous_home {
std::env::set_var("HOME", home);
} else {
std::env::remove_var("HOME");
}
let _ = std::fs::remove_dir_all(tempdir);
} }
#[test] #[test]
fn cycle_pane_layout_rotates_and_hides_log_when_leaving_grid() { fn cycle_pane_layout_rotates_and_hides_log_when_leaving_grid() {
let tempdir = std::env::temp_dir().join(format!("ecc2-cycle-pane-{}", Uuid::new_v4()));
std::fs::create_dir_all(&tempdir).unwrap();
let previous_home = std::env::var_os("HOME");
std::env::set_var("HOME", &tempdir);
let mut dashboard = test_dashboard(Vec::new(), 0); let mut dashboard = test_dashboard(Vec::new(), 0);
dashboard.cfg.pane_layout = PaneLayout::Grid; dashboard.cfg.pane_layout = PaneLayout::Grid;
dashboard.cfg.linear_pane_size_percent = 44; dashboard.cfg.linear_pane_size_percent = 44;
@@ -14648,13 +14247,6 @@ diff --git a/src/lib.rs b/src/lib.rs
assert_eq!(dashboard.cfg.pane_layout, PaneLayout::Horizontal); assert_eq!(dashboard.cfg.pane_layout, PaneLayout::Horizontal);
assert_eq!(dashboard.pane_size_percent, 44); assert_eq!(dashboard.pane_size_percent, 44);
assert_eq!(dashboard.selected_pane, Pane::Sessions); assert_eq!(dashboard.selected_pane, Pane::Sessions);
if let Some(home) = previous_home {
std::env::set_var("HOME", home);
} else {
std::env::remove_var("HOME");
}
let _ = std::fs::remove_dir_all(tempdir);
} }
#[test] #[test]
@@ -14940,7 +14532,6 @@ diff --git a/src/lib.rs b/src/lib.rs
approval_queue_counts: HashMap::new(), approval_queue_counts: HashMap::new(),
approval_queue_preview: Vec::new(), approval_queue_preview: Vec::new(),
handoff_backlog_counts: HashMap::new(), handoff_backlog_counts: HashMap::new(),
board_meta_by_session: HashMap::new(),
worktree_health_by_session: HashMap::new(), worktree_health_by_session: HashMap::new(),
global_handoff_backlog_leads: 0, global_handoff_backlog_leads: 0,
global_handoff_backlog_messages: 0, global_handoff_backlog_messages: 0,

642
yarn.lock
View File

@@ -100,6 +100,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@gar/promise-retry@npm:^1.0.0":
version: 1.0.3
resolution: "@gar/promise-retry@npm:1.0.3"
checksum: 10c0/885b02c8b0d75b2d215da25f3b639158c4fbe8fefe0d79163304534b9a6d0710db4b7699f7cd3cc1a730792bff04cbe19f4850a62d3e105a663eaeec88f38332
languageName: node
linkType: hard
"@humanfs/core@npm:^0.19.1": "@humanfs/core@npm:^0.19.1":
version: 0.19.1 version: 0.19.1
resolution: "@humanfs/core@npm:0.19.1" resolution: "@humanfs/core@npm:0.19.1"
@@ -138,6 +145,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@isaacs/fs-minipass@npm:^4.0.0":
version: 4.0.1
resolution: "@isaacs/fs-minipass@npm:4.0.1"
dependencies:
minipass: "npm:^7.0.4"
checksum: 10c0/c25b6dc1598790d5b55c0947a9b7d111cfa92594db5296c3b907e2f533c033666f692a3939eadac17b1c7c40d362d0b0635dc874cbfe3e70db7c2b07cc97a5d2
languageName: node
linkType: hard
"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": "@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3":
version: 0.1.3 version: 0.1.3
resolution: "@istanbuljs/schema@npm:0.1.3" resolution: "@istanbuljs/schema@npm:0.1.3"
@@ -169,30 +185,109 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@opencode-ai/plugin@npm:^1.0.0": "@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:3.0.3":
version: 1.3.15 version: 3.0.3
resolution: "@opencode-ai/plugin@npm:1.3.15" resolution: "@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:3.0.3"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-darwin-x64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-darwin-x64@npm:3.0.3"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-linux-arm64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-linux-arm64@npm:3.0.3"
conditions: os=linux & cpu=arm64
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-linux-arm@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-linux-arm@npm:3.0.3"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-linux-x64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-linux-x64@npm:3.0.3"
conditions: os=linux & cpu=x64
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-win32-x64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-win32-x64@npm:3.0.3"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@npmcli/agent@npm:^4.0.0":
version: 4.0.0
resolution: "@npmcli/agent@npm:4.0.0"
dependencies: dependencies:
"@opencode-ai/sdk": "npm:1.3.15" agent-base: "npm:^7.1.0"
http-proxy-agent: "npm:^7.0.0"
https-proxy-agent: "npm:^7.0.1"
lru-cache: "npm:^11.2.1"
socks-proxy-agent: "npm:^8.0.3"
checksum: 10c0/f7b5ce0f3dd42c3f8c6546e8433573d8049f67ef11ec22aa4704bc41483122f68bf97752e06302c455ead667af5cb753e6a09bff06632bc465c1cfd4c4b75a53
languageName: node
linkType: hard
"@npmcli/fs@npm:^5.0.0":
version: 5.0.0
resolution: "@npmcli/fs@npm:5.0.0"
dependencies:
semver: "npm:^7.3.5"
checksum: 10c0/26e376d780f60ff16e874a0ac9bc3399186846baae0b6e1352286385ac134d900cc5dafaded77f38d77f86898fc923ae1cee9d7399f0275b1aa24878915d722b
languageName: node
linkType: hard
"@npmcli/redact@npm:^4.0.0":
version: 4.0.0
resolution: "@npmcli/redact@npm:4.0.0"
checksum: 10c0/a1e9ba9c70a6b40e175bda2c3dd8cfdaf096e6b7f7a132c855c083c8dfe545c3237cd56702e2e6627a580b1d63373599d49a1192c4078a85bf47bbde824df31c
languageName: node
linkType: hard
"@opencode-ai/plugin@npm:^1.0.0":
version: 1.14.17
resolution: "@opencode-ai/plugin@npm:1.14.17"
dependencies:
"@opencode-ai/sdk": "npm:1.14.17"
effect: "npm:4.0.0-beta.48"
zod: "npm:4.1.8" zod: "npm:4.1.8"
peerDependencies: peerDependencies:
"@opentui/core": ">=0.1.96" "@opentui/core": ">=0.1.100"
"@opentui/solid": ">=0.1.96" "@opentui/solid": ">=0.1.100"
peerDependenciesMeta: peerDependenciesMeta:
"@opentui/core": "@opentui/core":
optional: true optional: true
"@opentui/solid": "@opentui/solid":
optional: true optional: true
checksum: 10c0/1a662ff700812223310612f3c8c7fd4465eda5763d726ec4d29d0eae26babf344ef176c9b987d79fe1e29c8a498178881a47d7080bb9f4db3e70dad59eb8cd9e checksum: 10c0/d1962bcc7a4f237050556a5557ce0db3ca0082d95e035ee795fe8623b2d88e536f0f44d48a14ea895407fc3db2faef2c95835b81408d8b9a2dec3115008e4986
languageName: node languageName: node
linkType: hard linkType: hard
"@opencode-ai/sdk@npm:1.3.15": "@opencode-ai/sdk@npm:1.14.17":
version: 1.3.15 version: 1.14.17
resolution: "@opencode-ai/sdk@npm:1.3.15" resolution: "@opencode-ai/sdk@npm:1.14.17"
dependencies: dependencies:
cross-spawn: "npm:7.0.6" cross-spawn: "npm:7.0.6"
checksum: 10c0/3957ae62e0ec1e339d9493e03a2440c95afdd64a608a2dc9db8383338650318a294280b2142305db5b0147badacbefa0d07e949d31167e5a4a49c9d057d016fa checksum: 10c0/74985b5967c7655afeb5ae54dc901c53eb123ce53c7af505b0e462d7a7d3e42dc997af40063735a2ad2fb4dcfce1aca2d3c45c5fa5c17a468f411b6b84d0e8b0
languageName: node
linkType: hard
"@standard-schema/spec@npm:^1.1.0":
version: 1.1.0
resolution: "@standard-schema/spec@npm:1.1.0"
checksum: 10c0/d90f55acde4b2deb983529c87e8025fa693de1a5e8b49ecc6eb84d1fd96328add0e03d7d551442156c7432fd78165b2c26ff561b970a9a881f046abb78d6a526
languageName: node languageName: node
linkType: hard linkType: hard
@@ -256,6 +351,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"abbrev@npm:^4.0.0":
version: 4.0.0
resolution: "abbrev@npm:4.0.0"
checksum: 10c0/b4cc16935235e80702fc90192e349e32f8ef0ed151ef506aa78c81a7c455ec18375c4125414b99f84b2e055199d66383e787675f0bcd87da7a4dbd59f9eac1d5
languageName: node
linkType: hard
"acorn-jsx@npm:^5.3.2": "acorn-jsx@npm:^5.3.2":
version: 5.3.2 version: 5.3.2
resolution: "acorn-jsx@npm:5.3.2" resolution: "acorn-jsx@npm:5.3.2"
@@ -274,6 +376,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"agent-base@npm:^7.1.0, agent-base@npm:^7.1.2":
version: 7.1.4
resolution: "agent-base@npm:7.1.4"
checksum: 10c0/c2c9ab7599692d594b6a161559ada307b7a624fa4c7b03e3afdb5a5e31cd0e53269115b620fcab024c5ac6a6f37fa5eb2e004f076ad30f5f7e6b8b671f7b35fe
languageName: node
linkType: hard
"ajv@npm:^6.12.4": "ajv@npm:^6.12.4":
version: 6.14.0 version: 6.14.0
resolution: "ajv@npm:6.14.0" resolution: "ajv@npm:6.14.0"
@@ -387,6 +496,24 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cacache@npm:^20.0.1":
version: 20.0.4
resolution: "cacache@npm:20.0.4"
dependencies:
"@npmcli/fs": "npm:^5.0.0"
fs-minipass: "npm:^3.0.0"
glob: "npm:^13.0.0"
lru-cache: "npm:^11.1.0"
minipass: "npm:^7.0.3"
minipass-collect: "npm:^2.0.1"
minipass-flush: "npm:^1.0.5"
minipass-pipeline: "npm:^1.2.4"
p-map: "npm:^7.0.2"
ssri: "npm:^13.0.0"
checksum: 10c0/539bf4020e44ba9ca5afc2ec435623ed7e0dd80c020097677e6b4a0545df5cc9d20b473212d01209c8b4aea43c0d095af0bb6da97bcb991642ea6fac0d7c462b
languageName: node
linkType: hard
"callsites@npm:^3.0.0": "callsites@npm:^3.0.0":
version: 3.1.0 version: 3.1.0
resolution: "callsites@npm:3.1.0" resolution: "callsites@npm:3.1.0"
@@ -425,6 +552,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"chownr@npm:^3.0.0":
version: 3.0.0
resolution: "chownr@npm:3.0.0"
checksum: 10c0/43925b87700f7e3893296c8e9c56cc58f926411cce3a6e5898136daaf08f08b9a8eb76d37d3267e707d0dcc17aed2e2ebdf5848c0c3ce95cf910a919935c1b10
languageName: node
linkType: hard
"cliui@npm:^8.0.1": "cliui@npm:^8.0.1":
version: 8.0.1 version: 8.0.1
resolution: "cliui@npm:8.0.1" resolution: "cliui@npm:8.0.1"
@@ -491,7 +625,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"debug@npm:^4.0.0, debug@npm:^4.3.1, debug@npm:^4.3.2": "debug@npm:4, debug@npm:^4.0.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4":
version: 4.4.3 version: 4.4.3
resolution: "debug@npm:4.4.3" resolution: "debug@npm:4.4.3"
dependencies: dependencies:
@@ -533,6 +667,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"detect-libc@npm:^2.0.1":
version: 2.1.2
resolution: "detect-libc@npm:2.1.2"
checksum: 10c0/acc675c29a5649fa1fb6e255f993b8ee829e510b6b56b0910666949c80c364738833417d0edb5f90e4e46be17228b0f2b66a010513984e18b15deeeac49369c4
languageName: node
linkType: hard
"devlop@npm:^1.0.0": "devlop@npm:^1.0.0":
version: 1.1.0 version: 1.1.0
resolution: "devlop@npm:1.1.0" resolution: "devlop@npm:1.1.0"
@@ -563,6 +704,24 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"effect@npm:4.0.0-beta.48":
version: 4.0.0-beta.48
resolution: "effect@npm:4.0.0-beta.48"
dependencies:
"@standard-schema/spec": "npm:^1.1.0"
fast-check: "npm:^4.6.0"
find-my-way-ts: "npm:^0.1.6"
ini: "npm:^6.0.0"
kubernetes-types: "npm:^1.30.0"
msgpackr: "npm:^1.11.9"
multipasta: "npm:^0.2.7"
toml: "npm:^4.1.1"
uuid: "npm:^13.0.0"
yaml: "npm:^2.8.3"
checksum: 10c0/dcd1ac9dbaa43b8bc3b3bd3ec1158b245c038c4522c2d3724d96243dc684773df21118cb2ed6fc648913ac6e9d5f016358d8495515f0c1863d81320b663ce312
languageName: node
linkType: hard
"emoji-regex@npm:^8.0.0": "emoji-regex@npm:^8.0.0":
version: 8.0.0 version: 8.0.0
resolution: "emoji-regex@npm:8.0.0" resolution: "emoji-regex@npm:8.0.0"
@@ -577,6 +736,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"env-paths@npm:^2.2.0":
version: 2.2.1
resolution: "env-paths@npm:2.2.1"
checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4
languageName: node
linkType: hard
"escalade@npm:^3.1.1": "escalade@npm:^3.1.1":
version: 3.2.0 version: 3.2.0
resolution: "escalade@npm:3.2.0" resolution: "escalade@npm:3.2.0"
@@ -707,6 +873,22 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"exponential-backoff@npm:^3.1.1":
version: 3.1.3
resolution: "exponential-backoff@npm:3.1.3"
checksum: 10c0/77e3ae682b7b1f4972f563c6dbcd2b0d54ac679e62d5d32f3e5085feba20483cf28bd505543f520e287a56d4d55a28d7874299941faf637e779a1aa5994d1267
languageName: node
linkType: hard
"fast-check@npm:^4.6.0":
version: 4.7.0
resolution: "fast-check@npm:4.7.0"
dependencies:
pure-rand: "npm:^8.0.0"
checksum: 10c0/7edce2b82d11d5325e9e79a2377e1f6e7200d27219edda2e3449d827e994c34461132fc149c90e41b78fc8e6ef4aae77d45350ac7bb1bc4a81110401d0a49fbc
languageName: node
linkType: hard
"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3":
version: 3.1.3 version: 3.1.3
resolution: "fast-deep-equal@npm:3.1.3" resolution: "fast-deep-equal@npm:3.1.3"
@@ -756,6 +938,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"find-my-way-ts@npm:^0.1.6":
version: 0.1.6
resolution: "find-my-way-ts@npm:0.1.6"
checksum: 10c0/16ad4b15275b56ee0ec361d0c61afbdff4c75bd0ac04112f6910f188cb1058096ba63529c2363914da6bb60266aa4def1025af04af26368ff87eb0df52f2862f
languageName: node
linkType: hard
"find-up@npm:^5.0.0": "find-up@npm:^5.0.0":
version: 5.0.0 version: 5.0.0
resolution: "find-up@npm:5.0.0" resolution: "find-up@npm:5.0.0"
@@ -793,6 +982,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"fs-minipass@npm:^3.0.0":
version: 3.0.3
resolution: "fs-minipass@npm:3.0.3"
dependencies:
minipass: "npm:^7.0.3"
checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94
languageName: node
linkType: hard
"get-caller-file@npm:^2.0.5": "get-caller-file@npm:^2.0.5":
version: 2.0.5 version: 2.0.5
resolution: "get-caller-file@npm:2.0.5" resolution: "get-caller-file@npm:2.0.5"
@@ -816,7 +1014,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"glob@npm:^13.0.6": "glob@npm:^13.0.0, glob@npm:^13.0.6":
version: 13.0.6 version: 13.0.6
resolution: "glob@npm:13.0.6" resolution: "glob@npm:13.0.6"
dependencies: dependencies:
@@ -835,9 +1033,16 @@ __metadata:
linkType: hard linkType: hard
"globals@npm:^17.4.0": "globals@npm:^17.4.0":
version: 17.4.0 version: 17.5.0
resolution: "globals@npm:17.4.0" resolution: "globals@npm:17.5.0"
checksum: 10c0/2be9e8c2b9035836f13d420b22f0247a328db82967d3bebfc01126d888ed609305f06c05895914e969653af5c6ba35fd7a0920f3e6c869afa60666c810630feb checksum: 10c0/92828102ed2f5637907725f0478038bed02fc83e9fc89300bb753639ba7c022b6c02576fc772117302b431b204591db1f2fa909d26f3f0a9852cc856a941df3f
languageName: node
linkType: hard
"graceful-fs@npm:^4.2.6":
version: 4.2.11
resolution: "graceful-fs@npm:4.2.11"
checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2
languageName: node languageName: node
linkType: hard linkType: hard
@@ -855,6 +1060,42 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"http-cache-semantics@npm:^4.1.1":
version: 4.2.0
resolution: "http-cache-semantics@npm:4.2.0"
checksum: 10c0/45b66a945cf13ec2d1f29432277201313babf4a01d9e52f44b31ca923434083afeca03f18417f599c9ab3d0e7b618ceb21257542338b57c54b710463b4a53e37
languageName: node
linkType: hard
"http-proxy-agent@npm:^7.0.0":
version: 7.0.2
resolution: "http-proxy-agent@npm:7.0.2"
dependencies:
agent-base: "npm:^7.1.0"
debug: "npm:^4.3.4"
checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921
languageName: node
linkType: hard
"https-proxy-agent@npm:^7.0.1":
version: 7.0.6
resolution: "https-proxy-agent@npm:7.0.6"
dependencies:
agent-base: "npm:^7.1.2"
debug: "npm:4"
checksum: 10c0/f729219bc735edb621fa30e6e84e60ee5d00802b8247aac0d7b79b0bd6d4b3294737a337b93b86a0bd9e68099d031858a39260c976dc14cdbba238ba1f8779ac
languageName: node
linkType: hard
"iconv-lite@npm:^0.7.2":
version: 0.7.2
resolution: "iconv-lite@npm:0.7.2"
dependencies:
safer-buffer: "npm:>= 2.1.2 < 3.0.0"
checksum: 10c0/3c228920f3bd307f56bf8363706a776f4a060eb042f131cd23855ceca962951b264d0997ab38a1ad340e1c5df8499ed26e1f4f0db6b2a2ad9befaff22f14b722
languageName: node
linkType: hard
"ignore@npm:^5.2.0": "ignore@npm:^5.2.0":
version: 5.3.2 version: 5.3.2
resolution: "ignore@npm:5.3.2" resolution: "ignore@npm:5.3.2"
@@ -886,6 +1127,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ini@npm:^6.0.0":
version: 6.0.0
resolution: "ini@npm:6.0.0"
checksum: 10c0/9a7f55f306e2b25b41ae67c8b526e8f4673f057b70852b9025816ef4f15f07bf1ba35ed68ea4471ff7b31718f7ef1bc50d709f8d03cb012e10a3135eb99c7206
languageName: node
linkType: hard
"ini@npm:~4.1.0": "ini@npm:~4.1.0":
version: 4.1.3 version: 4.1.3
resolution: "ini@npm:4.1.3" resolution: "ini@npm:4.1.3"
@@ -893,6 +1141,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ip-address@npm:^10.0.1":
version: 10.1.0
resolution: "ip-address@npm:10.1.0"
checksum: 10c0/0103516cfa93f6433b3bd7333fa876eb21263912329bfa47010af5e16934eeeff86f3d2ae700a3744a137839ddfad62b900c7a445607884a49b5d1e32a3d7566
languageName: node
linkType: hard
"is-alphabetical@npm:^2.0.0": "is-alphabetical@npm:^2.0.0":
version: 2.0.1 version: 2.0.1
resolution: "is-alphabetical@npm:2.0.1" resolution: "is-alphabetical@npm:2.0.1"
@@ -954,6 +1209,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"isexe@npm:^4.0.0":
version: 4.0.0
resolution: "isexe@npm:4.0.0"
checksum: 10c0/5884815115bceac452877659a9c7726382531592f43dc29e5d48b7c4100661aed54018cb90bd36cb2eaeba521092570769167acbb95c18d39afdccbcca06c5ce
languageName: node
linkType: hard
"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": "istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0":
version: 3.2.2 version: 3.2.2
resolution: "istanbul-lib-coverage@npm:3.2.2" resolution: "istanbul-lib-coverage@npm:3.2.2"
@@ -1055,6 +1317,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"kubernetes-types@npm:^1.30.0":
version: 1.30.0
resolution: "kubernetes-types@npm:1.30.0"
checksum: 10c0/de3641e4f50cfc123c4102a73c12932e1db8e51783c7cae4ea8ad3561bd56fab0f1c2346801f84a4c36aae8cea0b25d21e9514cc0fcecd4d64b1314043263076
languageName: node
linkType: hard
"levn@npm:^0.4.1": "levn@npm:^0.4.1":
version: 0.4.1 version: 0.4.1
resolution: "levn@npm:0.4.1" resolution: "levn@npm:0.4.1"
@@ -1097,6 +1366,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1":
version: 11.3.5
resolution: "lru-cache@npm:11.3.5"
checksum: 10c0/5b54ef7b88afb4bd25b7a778f1b2b1cde32d9770913e530da34ab203cf0442413bcaa6e372800cbab9562557a4480e4d8bf32e3a368bb5a91b12218eca085c66
languageName: node
linkType: hard
"make-dir@npm:^4.0.0": "make-dir@npm:^4.0.0":
version: 4.0.0 version: 4.0.0
resolution: "make-dir@npm:4.0.0" resolution: "make-dir@npm:4.0.0"
@@ -1106,6 +1382,26 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"make-fetch-happen@npm:^15.0.0":
version: 15.0.5
resolution: "make-fetch-happen@npm:15.0.5"
dependencies:
"@gar/promise-retry": "npm:^1.0.0"
"@npmcli/agent": "npm:^4.0.0"
"@npmcli/redact": "npm:^4.0.0"
cacache: "npm:^20.0.1"
http-cache-semantics: "npm:^4.1.1"
minipass: "npm:^7.0.2"
minipass-fetch: "npm:^5.0.0"
minipass-flush: "npm:^1.0.5"
minipass-pipeline: "npm:^1.2.4"
negotiator: "npm:^1.0.0"
proc-log: "npm:^6.0.0"
ssri: "npm:^13.0.0"
checksum: 10c0/527580eb5e5476e6ad07a4e3bd017d13e935f4be815674b442081ae5a721c13d3af5715006619e6be79a85723067e047f83a0c9e699f41d8cec43609a8de4f7b
languageName: node
linkType: hard
"markdown-it@npm:~14.1.1": "markdown-it@npm:~14.1.1":
version: 14.1.1 version: 14.1.1
resolution: "markdown-it@npm:14.1.1" resolution: "markdown-it@npm:14.1.1"
@@ -1488,13 +1784,82 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"minipass@npm:^7.1.2, minipass@npm:^7.1.3": "minipass-collect@npm:^2.0.1":
version: 2.0.1
resolution: "minipass-collect@npm:2.0.1"
dependencies:
minipass: "npm:^7.0.3"
checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e
languageName: node
linkType: hard
"minipass-fetch@npm:^5.0.0":
version: 5.0.2
resolution: "minipass-fetch@npm:5.0.2"
dependencies:
iconv-lite: "npm:^0.7.2"
minipass: "npm:^7.0.3"
minipass-sized: "npm:^2.0.0"
minizlib: "npm:^3.0.1"
dependenciesMeta:
iconv-lite:
optional: true
checksum: 10c0/ce4ab9f21cfabaead2097d95dd33f485af8072fbc6b19611bce694965393453a1639d641c2bcf1c48f2ea7d41ea7fab8278373f1d0bee4e63b0a5b2cdd0ef649
languageName: node
linkType: hard
"minipass-flush@npm:^1.0.5":
version: 1.0.7
resolution: "minipass-flush@npm:1.0.7"
dependencies:
minipass: "npm:^3.0.0"
checksum: 10c0/960915c02aa0991662c37c404517dd93708d17f96533b2ca8c1e776d158715d8107c5ced425ffc61674c167d93607f07f48a83c139ce1057f8781e5dfb4b90c2
languageName: node
linkType: hard
"minipass-pipeline@npm:^1.2.4":
version: 1.2.4
resolution: "minipass-pipeline@npm:1.2.4"
dependencies:
minipass: "npm:^3.0.0"
checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2
languageName: node
linkType: hard
"minipass-sized@npm:^2.0.0":
version: 2.0.0
resolution: "minipass-sized@npm:2.0.0"
dependencies:
minipass: "npm:^7.1.2"
checksum: 10c0/f9201696a6f6d68610d04c9c83e3d2e5cb9c026aae1c8cbf7e17f386105cb79c1bb088dbc21bf0b1eb4f3fb5df384fd1e7aa3bf1f33868c416ae8c8a92679db8
languageName: node
linkType: hard
"minipass@npm:^3.0.0":
version: 3.3.6
resolution: "minipass@npm:3.3.6"
dependencies:
yallist: "npm:^4.0.0"
checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c
languageName: node
linkType: hard
"minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3":
version: 7.1.3 version: 7.1.3
resolution: "minipass@npm:7.1.3" resolution: "minipass@npm:7.1.3"
checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb
languageName: node languageName: node
linkType: hard linkType: hard
"minizlib@npm:^3.0.1, minizlib@npm:^3.1.0":
version: 3.1.0
resolution: "minizlib@npm:3.1.0"
dependencies:
minipass: "npm:^7.1.2"
checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec
languageName: node
linkType: hard
"ms@npm:^2.1.3": "ms@npm:^2.1.3":
version: 2.1.3 version: 2.1.3
resolution: "ms@npm:2.1.3" resolution: "ms@npm:2.1.3"
@@ -1502,6 +1867,56 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"msgpackr-extract@npm:^3.0.2":
version: 3.0.3
resolution: "msgpackr-extract@npm:3.0.3"
dependencies:
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-darwin-x64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-arm": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-arm64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-x64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-win32-x64": "npm:3.0.3"
node-gyp: "npm:latest"
node-gyp-build-optional-packages: "npm:5.2.2"
dependenciesMeta:
"@msgpackr-extract/msgpackr-extract-darwin-arm64":
optional: true
"@msgpackr-extract/msgpackr-extract-darwin-x64":
optional: true
"@msgpackr-extract/msgpackr-extract-linux-arm":
optional: true
"@msgpackr-extract/msgpackr-extract-linux-arm64":
optional: true
"@msgpackr-extract/msgpackr-extract-linux-x64":
optional: true
"@msgpackr-extract/msgpackr-extract-win32-x64":
optional: true
bin:
download-msgpackr-prebuilds: bin/download-prebuilds.js
checksum: 10c0/e504fd8bf86a29d7527c83776530ee6dc92dcb0273bb3679fd4a85173efead7f0ee32fb82c8410a13c33ef32828c45f81118ffc0fbed5d6842e72299894623b4
languageName: node
linkType: hard
"msgpackr@npm:^1.11.9":
version: 1.11.10
resolution: "msgpackr@npm:1.11.10"
dependencies:
msgpackr-extract: "npm:^3.0.2"
dependenciesMeta:
msgpackr-extract:
optional: true
checksum: 10c0/fa5b8b90661cc66127d4550bc3757d0e72fe3217a47f952acd0df647afb4593ffde0bbdb1c9f5a13b9df15d5a170a570a59728dd7ede9b0d711e20e4f970fa82
languageName: node
linkType: hard
"multipasta@npm:^0.2.7":
version: 0.2.7
resolution: "multipasta@npm:0.2.7"
checksum: 10c0/15917ac88aeefa5b8afac44b90d1e9d0d0ec7148b51e0766f07a69a220ecebcb6404539a856c45aa85a3d7fe517bc58febe81437146705f17ecd2961dc0b9fa5
languageName: node
linkType: hard
"natural-compare@npm:^1.4.0": "natural-compare@npm:^1.4.0":
version: 1.4.0 version: 1.4.0
resolution: "natural-compare@npm:1.4.0" resolution: "natural-compare@npm:1.4.0"
@@ -1509,6 +1924,57 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"negotiator@npm:^1.0.0":
version: 1.0.0
resolution: "negotiator@npm:1.0.0"
checksum: 10c0/4c559dd52669ea48e1914f9d634227c561221dd54734070791f999c52ed0ff36e437b2e07d5c1f6e32909fc625fe46491c16e4a8f0572567d4dd15c3a4fda04b
languageName: node
linkType: hard
"node-gyp-build-optional-packages@npm:5.2.2":
version: 5.2.2
resolution: "node-gyp-build-optional-packages@npm:5.2.2"
dependencies:
detect-libc: "npm:^2.0.1"
bin:
node-gyp-build-optional-packages: bin.js
node-gyp-build-optional-packages-optional: optional.js
node-gyp-build-optional-packages-test: build-test.js
checksum: 10c0/c81128c6f91873381be178c5eddcbdf66a148a6a89a427ce2bcd457593ce69baf2a8662b6d22cac092d24aa9c43c230dec4e69b3a0da604503f4777cd77e282b
languageName: node
linkType: hard
"node-gyp@npm:latest":
version: 12.2.0
resolution: "node-gyp@npm:12.2.0"
dependencies:
env-paths: "npm:^2.2.0"
exponential-backoff: "npm:^3.1.1"
graceful-fs: "npm:^4.2.6"
make-fetch-happen: "npm:^15.0.0"
nopt: "npm:^9.0.0"
proc-log: "npm:^6.0.0"
semver: "npm:^7.3.5"
tar: "npm:^7.5.4"
tinyglobby: "npm:^0.2.12"
which: "npm:^6.0.0"
bin:
node-gyp: bin/node-gyp.js
checksum: 10c0/3ed046746a5a7d90950cd8b0547332b06598443f31fe213ef4332a7174c7b7d259e1704835feda79b87d3f02e59d7791842aac60642ede4396ab25fdf0f8f759
languageName: node
linkType: hard
"nopt@npm:^9.0.0":
version: 9.0.0
resolution: "nopt@npm:9.0.0"
dependencies:
abbrev: "npm:^4.0.0"
bin:
nopt: bin/nopt.js
checksum: 10c0/1822eb6f9b020ef6f7a7516d7b64a8036e09666ea55ac40416c36e4b2b343122c3cff0e2f085675f53de1d2db99a2a89a60ccea1d120bcd6a5347bf6ceb4a7fd
languageName: node
linkType: hard
"optionator@npm:^0.9.3": "optionator@npm:^0.9.3":
version: 0.9.4 version: 0.9.4
resolution: "optionator@npm:0.9.4" resolution: "optionator@npm:0.9.4"
@@ -1541,6 +2007,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"p-map@npm:^7.0.2":
version: 7.0.4
resolution: "p-map@npm:7.0.4"
checksum: 10c0/a5030935d3cb2919d7e89454d1ce82141e6f9955413658b8c9403cfe379283770ed3048146b44cde168aa9e8c716505f196d5689db0ae3ce9a71521a2fef3abd
languageName: node
linkType: hard
"parent-module@npm:^1.0.0": "parent-module@npm:^1.0.0":
version: 1.0.1 version: 1.0.1
resolution: "parent-module@npm:1.0.1" resolution: "parent-module@npm:1.0.1"
@@ -1589,7 +2062,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"picomatch@npm:^4.0.3": "picomatch@npm:^4.0.3, picomatch@npm:^4.0.4":
version: 4.0.4 version: 4.0.4
resolution: "picomatch@npm:4.0.4" resolution: "picomatch@npm:4.0.4"
checksum: 10c0/e2c6023372cc7b5764719a5ffb9da0f8e781212fa7ca4bd0562db929df8e117460f00dff3cb7509dacfc06b86de924b247f504d0ce1806a37fac4633081466b0 checksum: 10c0/e2c6023372cc7b5764719a5ffb9da0f8e781212fa7ca4bd0562db929df8e117460f00dff3cb7509dacfc06b86de924b247f504d0ce1806a37fac4633081466b0
@@ -1603,6 +2076,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"proc-log@npm:^6.0.0":
version: 6.1.0
resolution: "proc-log@npm:6.1.0"
checksum: 10c0/4f178d4062733ead9d71a9b1ab24ebcecdfe2250916a5b1555f04fe2eda972a0ec76fbaa8df1ad9c02707add6749219d118a4fc46dc56bdfe4dde4b47d80bb82
languageName: node
linkType: hard
"punycode.js@npm:^2.3.1": "punycode.js@npm:^2.3.1":
version: 2.3.1 version: 2.3.1
resolution: "punycode.js@npm:2.3.1" resolution: "punycode.js@npm:2.3.1"
@@ -1617,6 +2097,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"pure-rand@npm:^8.0.0":
version: 8.4.0
resolution: "pure-rand@npm:8.4.0"
checksum: 10c0/6414bbc1c6f45fb774173431c7205e79783b77cfae0e2145e741b6999363554dbd2f4210d2a5bc08683e0b2f6823198c9308766b1d0911e1dccd7beb8842f860
languageName: node
linkType: hard
"require-directory@npm:^2.1.1": "require-directory@npm:^2.1.1":
version: 2.1.1 version: 2.1.1
resolution: "require-directory@npm:2.1.1" resolution: "require-directory@npm:2.1.1"
@@ -1652,7 +2139,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"semver@npm:^7.5.3": "safer-buffer@npm:>= 2.1.2 < 3.0.0":
version: 2.1.2
resolution: "safer-buffer@npm:2.1.2"
checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4
languageName: node
linkType: hard
"semver@npm:^7.3.5, semver@npm:^7.5.3":
version: 7.7.4 version: 7.7.4
resolution: "semver@npm:7.7.4" resolution: "semver@npm:7.7.4"
bin: bin:
@@ -1684,6 +2178,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"smart-buffer@npm:^4.2.0":
version: 4.2.0
resolution: "smart-buffer@npm:4.2.0"
checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539
languageName: node
linkType: hard
"smol-toml@npm:~1.6.0": "smol-toml@npm:~1.6.0":
version: 1.6.1 version: 1.6.1
resolution: "smol-toml@npm:1.6.1" resolution: "smol-toml@npm:1.6.1"
@@ -1691,6 +2192,27 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"socks-proxy-agent@npm:^8.0.3":
version: 8.0.5
resolution: "socks-proxy-agent@npm:8.0.5"
dependencies:
agent-base: "npm:^7.1.2"
debug: "npm:^4.3.4"
socks: "npm:^2.8.3"
checksum: 10c0/5d2c6cecba6821389aabf18728325730504bf9bb1d9e342e7987a5d13badd7a98838cc9a55b8ed3cb866ad37cc23e1086f09c4d72d93105ce9dfe76330e9d2a6
languageName: node
linkType: hard
"socks@npm:^2.8.3":
version: 2.8.7
resolution: "socks@npm:2.8.7"
dependencies:
ip-address: "npm:^10.0.1"
smart-buffer: "npm:^4.2.0"
checksum: 10c0/2805a43a1c4bcf9ebf6e018268d87b32b32b06fbbc1f9282573583acc155860dc361500f89c73bfbb157caa1b4ac78059eac0ef15d1811eb0ca75e0bdadbc9d2
languageName: node
linkType: hard
"sql.js@npm:^1.14.1": "sql.js@npm:^1.14.1":
version: 1.14.1 version: 1.14.1
resolution: "sql.js@npm:1.14.1" resolution: "sql.js@npm:1.14.1"
@@ -1698,6 +2220,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ssri@npm:^13.0.0":
version: 13.0.1
resolution: "ssri@npm:13.0.1"
dependencies:
minipass: "npm:^7.0.3"
checksum: 10c0/cf6408a18676c57ff2ed06b8a20dc64bb3e748e5c7e095332e6aecaa2b8422b1e94a739a8453bf65156a8a47afe23757ba4ab52d3ea3b62322dc40875763e17a
languageName: node
linkType: hard
"string-width@npm:8.1.0": "string-width@npm:8.1.0":
version: 8.1.0 version: 8.1.0
resolution: "string-width@npm:8.1.0" resolution: "string-width@npm:8.1.0"
@@ -1753,6 +2284,19 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"tar@npm:^7.5.4":
version: 7.5.13
resolution: "tar@npm:7.5.13"
dependencies:
"@isaacs/fs-minipass": "npm:^4.0.0"
chownr: "npm:^3.0.0"
minipass: "npm:^7.1.2"
minizlib: "npm:^3.1.0"
yallist: "npm:^5.0.0"
checksum: 10c0/5c65b8084799bde7a791593a1c1a45d3d6ee98182e3700b24c247b7b8f8654df4191642abbdb07ff25043d45dcff35620827c3997b88ae6c12040f64bed5076b
languageName: node
linkType: hard
"test-exclude@npm:^8.0.0": "test-exclude@npm:^8.0.0":
version: 8.0.0 version: 8.0.0
resolution: "test-exclude@npm:8.0.0" resolution: "test-exclude@npm:8.0.0"
@@ -1764,6 +2308,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"tinyglobby@npm:^0.2.12":
version: 0.2.16
resolution: "tinyglobby@npm:0.2.16"
dependencies:
fdir: "npm:^6.5.0"
picomatch: "npm:^4.0.4"
checksum: 10c0/f2e09fd93dd95c41e522113b686ff6f7c13020962f8698a864a257f3d7737599afc47722b7ab726e12f8a813f779906187911ff8ee6701ede65072671a7e934b
languageName: node
linkType: hard
"tinyglobby@npm:~0.2.15": "tinyglobby@npm:~0.2.15":
version: 0.2.15 version: 0.2.15
resolution: "tinyglobby@npm:0.2.15" resolution: "tinyglobby@npm:0.2.15"
@@ -1774,6 +2328,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"toml@npm:^4.1.1":
version: 4.1.1
resolution: "toml@npm:4.1.1"
checksum: 10c0/077bc02ac1ce82091ea073f675d7e2a1df487d1b18bbc7e653daba4956d545954b7095e979b8792f0837339b901ee190ad4464342e5e377c36bbdeca8903e079
languageName: node
linkType: hard
"type-check@npm:^0.4.0, type-check@npm:~0.4.0": "type-check@npm:^0.4.0, type-check@npm:~0.4.0":
version: 0.4.0 version: 0.4.0
resolution: "type-check@npm:0.4.0" resolution: "type-check@npm:0.4.0"
@@ -1826,6 +2387,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"uuid@npm:^13.0.0":
version: 13.0.0
resolution: "uuid@npm:13.0.0"
bin:
uuid: dist-node/bin/uuid
checksum: 10c0/950e4c18d57fef6c69675344f5700a08af21e26b9eff2bf2180427564297368c538ea11ac9fb2e6528b17fc3966a9fd2c5049361b0b63c7d654f3c550c9b3d67
languageName: node
linkType: hard
"v8-to-istanbul@npm:^9.0.0": "v8-to-istanbul@npm:^9.0.0":
version: 9.3.0 version: 9.3.0
resolution: "v8-to-istanbul@npm:9.3.0" resolution: "v8-to-istanbul@npm:9.3.0"
@@ -1848,6 +2418,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"which@npm:^6.0.0":
version: 6.0.1
resolution: "which@npm:6.0.1"
dependencies:
isexe: "npm:^4.0.0"
bin:
node-which: bin/which.js
checksum: 10c0/7e710e54ea36d2d6183bee2f9caa27a3b47b9baf8dee55a199b736fcf85eab3b9df7556fca3d02b50af7f3dfba5ea3a45644189836df06267df457e354da66d5
languageName: node
linkType: hard
"word-wrap@npm:^1.2.5": "word-wrap@npm:^1.2.5":
version: 1.2.5 version: 1.2.5
resolution: "word-wrap@npm:1.2.5" resolution: "word-wrap@npm:1.2.5"
@@ -1873,6 +2454,29 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"yallist@npm:^4.0.0":
version: 4.0.0
resolution: "yallist@npm:4.0.0"
checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a
languageName: node
linkType: hard
"yallist@npm:^5.0.0":
version: 5.0.0
resolution: "yallist@npm:5.0.0"
checksum: 10c0/a499c81ce6d4a1d260d4ea0f6d49ab4da09681e32c3f0472dee16667ed69d01dae63a3b81745a24bd78476ec4fcf856114cb4896ace738e01da34b2c42235416
languageName: node
linkType: hard
"yaml@npm:^2.8.3":
version: 2.8.3
resolution: "yaml@npm:2.8.3"
bin:
yaml: bin.mjs
checksum: 10c0/ddff0e11c1b467728d7eb4633db61c5f5de3d8e9373cf84d08fb0cdee03e1f58f02b9f1c51a4a8a865751695addbd465a77f73f1079be91fe5493b29c305fd77
languageName: node
linkType: hard
"yargs-parser@npm:^21.1.1": "yargs-parser@npm:^21.1.1":
version: 21.1.1 version: 21.1.1
resolution: "yargs-parser@npm:21.1.1" resolution: "yargs-parser@npm:21.1.1"